feat: completed base feature set for the app

This commit is contained in:
2026-07-18 20:25:17 +02:00
parent e9d6c70eb0
commit 638202b96c
46 changed files with 4486 additions and 541 deletions

View File

@@ -4,6 +4,23 @@ fn default_max_posts() -> i32 {
50
}
fn default_image_import_concurrency() -> i32 {
4
}
fn deserialize_image_import_concurrency<'de, D>(deserializer: D) -> Result<i32, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = serde_json::Value::deserialize(deserializer)?;
let parsed = value
.as_i64()
.map(|value| value as i32)
.or_else(|| value.as_str().and_then(|value| value.parse::<i32>().ok()))
.unwrap_or_else(default_image_import_concurrency);
Ok(parsed.clamp(1, 8))
}
fn default_true() -> bool {
true
}
@@ -22,6 +39,11 @@ pub struct ProjectMetadata {
pub default_author: Option<String>,
#[serde(default = "default_max_posts")]
pub max_posts_per_page: i32,
#[serde(
default = "default_image_import_concurrency",
deserialize_with = "deserialize_image_import_concurrency"
)]
pub image_import_concurrency: i32,
#[serde(skip_serializing_if = "Option::is_none")]
pub blogmark_category: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
@@ -41,6 +63,12 @@ impl ProjectMetadata {
self.max_posts_per_page
));
}
if !(1..=8).contains(&self.image_import_concurrency) {
return Err(format!(
"imageImportConcurrency must be 1..8, got {}",
self.image_import_concurrency
));
}
Ok(())
}
}
@@ -80,6 +108,7 @@ mod tests {
main_language: Some("en".into()),
default_author: None,
max_posts_per_page: 50,
image_import_concurrency: 4,
blogmark_category: None,
pico_theme: None,
semantic_similarity_enabled: false,
@@ -101,6 +130,7 @@ mod tests {
let json = r#"{"name": "Minimal"}"#;
let meta: ProjectMetadata = serde_json::from_str(json).unwrap();
assert_eq!(meta.max_posts_per_page, 50);
assert_eq!(meta.image_import_concurrency, 4);
assert!(!meta.semantic_similarity_enabled);
assert!(meta.blog_languages.is_empty());
}
@@ -159,6 +189,7 @@ mod tests {
main_language: None,
default_author: None,
max_posts_per_page: 50,
image_import_concurrency: 4,
blogmark_category: None,
pico_theme: None,
semantic_similarity_enabled: false,