From 123cfec58b219c31dfee3a6e9125b8812850eb37 Mon Sep 17 00:00:00 2001 From: Alex Good Date: Tue, 4 Jun 2024 10:47:29 +0100 Subject: [PATCH] Implement Reconcile for MaybeMissing --- autosurgeon/src/hydrate.rs | 13 ++++++++++- autosurgeon/src/lib.rs | 2 +- autosurgeon/src/reconcile.rs | 45 ++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/autosurgeon/src/hydrate.rs b/autosurgeon/src/hydrate.rs index 4d8ecdc..a37ea53 100644 --- a/autosurgeon/src/hydrate.rs +++ b/autosurgeon/src/hydrate.rs @@ -298,7 +298,7 @@ impl HydrateResultExt> for Result, HydrateError> { /// Note that this can be combined with `Option` to get both behaviours /// /// ```rust -/// # use autosurgeon::{Hydrate, hydrate::MaybeMissing}; +/// # use autosurgeon::{Hydrate, MaybeMissing}; /// # use automerge::transaction::Transactable; /// let mut doc = automerge::AutoCommit::new(); /// let name = MaybeMissing::>::hydrate(&doc, &automerge::ROOT, "name".into()).unwrap(); @@ -332,6 +332,17 @@ impl Hydrate for MaybeMissing { } } +impl crate::Reconcile for MaybeMissing { + type Key<'a> = T::Key<'a>; + + fn reconcile(&self, reconciler: R) -> Result<(), R::Error> { + match self { + Self::Missing => Ok(()), + Self::Present(val) => val.reconcile(reconciler), + } + } +} + impl MaybeMissing { pub fn unwrap_or_else(self, f: F) -> T where diff --git a/autosurgeon/src/lib.rs b/autosurgeon/src/lib.rs index 6344670..698ff7c 100644 --- a/autosurgeon/src/lib.rs +++ b/autosurgeon/src/lib.rs @@ -459,7 +459,7 @@ mod doc; pub use doc::{Doc, ReadDoc}; pub mod hydrate; #[doc(inline)] -pub use hydrate::{hydrate, hydrate_path, hydrate_prop, Hydrate, HydrateError}; +pub use hydrate::{hydrate, hydrate_path, hydrate_prop, Hydrate, HydrateError, MaybeMissing}; pub mod reconcile; #[doc(inline)] pub use reconcile::{ diff --git a/autosurgeon/src/reconcile.rs b/autosurgeon/src/reconcile.rs index 81ef82f..53adad3 100644 --- a/autosurgeon/src/reconcile.rs +++ b/autosurgeon/src/reconcile.rs @@ -1093,4 +1093,49 @@ mod tests { }} ); } + + struct Foo { + bar: crate::hydrate::MaybeMissing, + } + + impl crate::Reconcile for Foo { + type Key<'a> = NoKey; + + fn reconcile(&self, mut reconciler: R) -> Result<(), R::Error> { + let mut map = reconciler.map()?; + map.put("bar", &self.bar)?; + Ok(()) + } + } + + #[test] + fn reconcile_maybe_missing_present() { + let mut doc = automerge::AutoCommit::new(); + reconcile( + &mut doc, + &Foo { + bar: crate::MaybeMissing::Present("baz".to_string()), + }, + ) + .unwrap(); + let val = doc.get(&automerge::ROOT, "bar").unwrap().unwrap(); + assert_eq!( + val.0, + automerge::Value::Scalar(std::borrow::Cow::Owned(ScalarValue::Str("baz".into()))) + ); + } + + #[test] + fn reconcile_maybe_missing_not_present() { + let mut doc = automerge::AutoCommit::new(); + reconcile( + &mut doc, + &Foo { + bar: crate::MaybeMissing::Missing, + }, + ) + .unwrap(); + let val = doc.get(&automerge::ROOT, "bar").unwrap(); + assert!(val.is_none()); + } }