From 709f8cbf3c5146a0f53a6e9b6a4aeb3abd1aff35 Mon Sep 17 00:00:00 2001 From: Vika Date: Sat, 1 Jul 2023 20:40:38 +0300 Subject: micropub: use the new, better typed updates internally --- kittybox-rs/src/micropub/mod.rs | 45 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'kittybox-rs/src/micropub') diff --git a/kittybox-rs/src/micropub/mod.rs b/kittybox-rs/src/micropub/mod.rs index a55ea15..fe3db57 100644 --- a/kittybox-rs/src/micropub/mod.rs +++ b/kittybox-rs/src/micropub/mod.rs @@ -56,9 +56,9 @@ fn populate_reply_context( mf2: &serde_json::Value, prop: &str, ctxs: &[FetchedPostContext], -) -> Option { +) -> Option> { mf2["properties"][prop].as_array().map(|array| { - json!(array + array .iter() // TODO: This seems to be O(n^2) and I don't like it. // Switching `ctxs` to a hashmap might speed it up to O(n) @@ -68,7 +68,8 @@ fn populate_reply_context( .find(|ctx| Some(ctx.url.as_str()) == i.as_str()) .and_then(|ctx| ctx.mf2["items"].get(0)) .unwrap_or(i)) - .collect::>()) + .cloned() + .collect::>() }) } @@ -147,13 +148,16 @@ async fn background_processing( .await }; - let mut update = json!({ "replace": {} }); - for prop in &context_props { + let mut update = MicropubUpdate { + replace: Some(Default::default()), + ..Default::default() + }; + for prop in context_props { if let Some(json) = populate_reply_context(&mf2, prop, &post_contexts) { - update["replace"][prop] = json; + update.replace.as_mut().unwrap().insert(prop.to_owned(), json); } } - if !update["replace"].as_object().unwrap().is_empty() { + if !update.replace.as_ref().unwrap().is_empty() { if let Err(err) = db.update_post(uid, update).await { error!("Failed to update post with rich reply contexts: {}", err); } @@ -323,7 +327,7 @@ enum ActionType { #[serde(untagged)] pub enum MicropubPropertyDeletion { Properties(Vec), - Values(HashMap) + Values(HashMap>) } #[derive(Serialize, Deserialize)] struct MicropubFormAction { @@ -335,12 +339,20 @@ struct MicropubFormAction { pub struct MicropubAction { action: ActionType, url: String, + #[serde(flatten)] #[serde(skip_serializing_if = "Option::is_none")] - replace: Option>, + update: Option +} + +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct MicropubUpdate { #[serde(skip_serializing_if = "Option::is_none")] - add: Option>, + pub replace: Option>>, #[serde(skip_serializing_if = "Option::is_none")] - delete: Option, + pub add: Option>>, + #[serde(skip_serializing_if = "Option::is_none")] + pub delete: Option, + } impl From for MicropubAction { @@ -349,9 +361,7 @@ impl From for MicropubAction { Self { action: a.action, url: a.url, - replace: None, - add: None, - delete: None, + update: None } } } @@ -407,9 +417,10 @@ async fn post_action( db.update_post( &action.url, - // Here, unwrapping is safe, because this value - // was recently deserialized from JSON already. - serde_json::to_value(&action).unwrap(), + action.update.ok_or(MicropubError { + error: ErrorType::InvalidRequest, + error_description: "Update request is not set.".to_owned(), + })? ) .await? } -- cgit 1.4.1