use serde::{Deserialize, Serialize}; /// apply a bool patch or set replacement for a single set update. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(untagged)] pub(crate) enum SetUpdate { /// replace the entire set with this list Set(Vec), /// patch: true = add, false = remove Patch(std::collections::HashMap), } #[cfg(test)] mod tests { use super::*; #[test] fn set_update_json_markers_are_structurally_disjoint() { for input in [r#"[]"#, r#"["a","b"]"#] { let update: SetUpdate = serde_json::from_str(input).unwrap(); assert!(matches!(update, SetUpdate::Set(_)), "{input}"); } for input in [r#"{}"#, r#"{"a":true,"b":false}"#] { let update: SetUpdate = serde_json::from_str(input).unwrap(); assert!(matches!(update, SetUpdate::Patch(_)), "{input}"); } for input in [r#""a""#, "null", "true", "1"] { assert!(serde_json::from_str::(input).is_err(), "{input}"); } } #[test] fn set_update_json_roundtrips_both_variants() { for update in [ SetUpdate::Set(vec!["a".to_owned(), "b".to_owned()]), SetUpdate::Patch([("a".to_owned(), true), ("b".to_owned(), false)].into()), ] { let encoded = serde_json::to_vec(&update).unwrap(); let decoded: SetUpdate = serde_json::from_slice(&encoded).unwrap(); assert_eq!(decoded, update); } } }