diff options
Diffstat (limited to 'src/micropub')
-rw-r--r-- | src/micropub/mod.rs | 39 |
1 files changed, 38 insertions, 1 deletions
diff --git a/src/micropub/mod.rs b/src/micropub/mod.rs index 8f95085..944506d 100644 --- a/src/micropub/mod.rs +++ b/src/micropub/mod.rs @@ -358,7 +358,44 @@ pub struct MicropubUpdate { pub add: Option<HashMap<String, Vec<serde_json::Value>>>, #[serde(skip_serializing_if = "Option::is_none")] pub delete: Option<MicropubPropertyDeletion>, - +} +impl MicropubUpdate { + /// Update a specified MF2-JSON document with this update. + pub fn apply(self, post: &mut serde_json::Value) { + if let Some(MicropubPropertyDeletion::Properties(ref delete)) = self.delete { + if let Some(props) = post["properties"].as_object_mut() { + for key in delete { + props.remove(key); + } + } + } else if let Some(MicropubPropertyDeletion::Values(ref delete)) = self.delete { + if let Some(props) = post["properties"].as_object_mut() { + for (key, values) in delete { + if let Some(prop) = props.get_mut(key).and_then(serde_json::Value::as_array_mut) { + prop.retain(|v| { values.iter().all(|i| i != v) }) + } + } + } + } + if let Some(replace) = self.replace { + if let Some(props) = post["properties"].as_object_mut() { + for (key, value) in replace { + props.insert(key, serde_json::Value::Array(value)); + } + } + } + if let Some(add) = self.add { + if let Some(props) = post["properties"].as_object_mut() { + for (key, value) in add { + if let Some(prop) = props.get_mut(&key).and_then(serde_json::Value::as_array_mut) { + prop.extend_from_slice(value.as_slice()); + } else { + props.insert(key, serde_json::Value::Array(value)); + } + } + } + } + } } impl From<MicropubFormAction> for MicropubAction { |