diff options
Diffstat (limited to 'kittybox-rs/src/micropub')
-rw-r--r-- | kittybox-rs/src/micropub/mod.rs | 45 |
1 files changed, 28 insertions, 17 deletions
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<serde_json::Value> { +) -> Option<Vec<serde_json::Value>> { 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::<Vec<&serde_json::Value>>()) + .cloned() + .collect::<Vec<serde_json::Value>>() }) } @@ -147,13 +148,16 @@ async fn background_processing<D: 'static + Storage>( .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<String>), - Values(HashMap<String, serde_json::Value>) + Values(HashMap<String, Vec<serde_json::Value>>) } #[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<HashMap<String, serde_json::Value>>, + update: Option<MicropubUpdate> +} + +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct MicropubUpdate { #[serde(skip_serializing_if = "Option::is_none")] - add: Option<HashMap<String, serde_json::Value>>, + pub replace: Option<HashMap<String, Vec<serde_json::Value>>>, #[serde(skip_serializing_if = "Option::is_none")] - delete: Option<MicropubPropertyDeletion>, + pub add: Option<HashMap<String, Vec<serde_json::Value>>>, + #[serde(skip_serializing_if = "Option::is_none")] + pub delete: Option<MicropubPropertyDeletion>, + } impl From<MicropubFormAction> for MicropubAction { @@ -349,9 +361,7 @@ impl From<MicropubFormAction> 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<D: Storage, A: AuthBackend>( 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? } |