From 8c89e3af49985ede112ec6fb4e908c801800924a Mon Sep 17 00:00:00 2001 From: Alex Good Date: Fri, 21 Jul 2023 23:25:18 +0100 Subject: [PATCH] Update to automerge@0.5.0 --- autosurgeon-derive/Cargo.toml | 4 +- autosurgeon-derive/src/reconcile/enum_impl.rs | 3 +- autosurgeon/Cargo.toml | 4 +- autosurgeon/src/doc.rs | 46 ++++++++++--------- autosurgeon/src/hydrate/map.rs | 4 +- autosurgeon/src/reconcile.rs | 14 +++--- autosurgeon/src/text.rs | 18 ++++++-- 7 files changed, 53 insertions(+), 40 deletions(-) diff --git a/autosurgeon-derive/Cargo.toml b/autosurgeon-derive/Cargo.toml index d1a62b8..be51cb4 100644 --- a/autosurgeon-derive/Cargo.toml +++ b/autosurgeon-derive/Cargo.toml @@ -20,5 +20,5 @@ thiserror = "1.0.37" [dev-dependencies] autosurgeon = { path = "../autosurgeon" } -automerge = { version = "0.4.0" } -automerge-test = "0.3.0" +automerge = { version = "0.5.0" } +automerge-test = "0.4.0" diff --git a/autosurgeon-derive/src/reconcile/enum_impl.rs b/autosurgeon-derive/src/reconcile/enum_impl.rs index e511510..6f47bd8 100644 --- a/autosurgeon-derive/src/reconcile/enum_impl.rs +++ b/autosurgeon-derive/src/reconcile/enum_impl.rs @@ -460,7 +460,6 @@ impl<'a> EnumKey<'a> { let key_type_name = self.type_name(); let outer_id_ident = syn::Ident::new("outer_id", Span::mixed_site()); - let inner_id_ident = syn::Ident::new("inner_id", Span::mixed_site()); let non_unit_match_arms = self .variants @@ -492,7 +491,7 @@ impl<'a> EnumKey<'a> { _ => Ok(autosurgeon::reconcile::LoadKey::KeyNotFound) }, Value::Object(ObjType::Map) => { - let Some((discriminant_str, inner_ty, #inner_id_ident)) = doc.map_range(&#outer_id_ident, ..).next() else { + let Some(automerge::iter::MapRangeItem{key: discriminant_str, ..}) = doc.map_range(&#outer_id_ident, ..).next() else { return Ok(autosurgeon::reconcile::LoadKey::KeyNotFound); }; match discriminant_str { diff --git a/autosurgeon/Cargo.toml b/autosurgeon/Cargo.toml index ecd6e2b..3a6e661 100644 --- a/autosurgeon/Cargo.toml +++ b/autosurgeon/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/automerge/autosurgeon" readme = "../README.md" [dependencies] -automerge = { version = "0.4.0" } +automerge = { version = "0.5.0" } thiserror = "1.0.37" smol_str = { version = "^0.1.21" } autosurgeon-derive = { path = "../autosurgeon-derive", version = "0.6.0" } @@ -18,7 +18,7 @@ similar = "2.2.1" uuid = { version = "1.2.2", optional = true } [dev-dependencies] -automerge-test = "0.3.0" +automerge-test = "0.4.0" [features] uuid = ["dep:uuid"] diff --git a/autosurgeon/src/doc.rs b/autosurgeon/src/doc.rs index c25bf9b..a9eaf60 100644 --- a/autosurgeon/src/doc.rs +++ b/autosurgeon/src/doc.rs @@ -16,17 +16,19 @@ pub trait ReadDoc { ) -> Result, ObjId)>, AutomergeError>; fn object_type>(&self, obj: O) -> Option; - fn map_range, R: RangeBounds>( - &self, + fn map_range<'a, O: AsRef, R: RangeBounds>( + &'a self, obj: O, range: R, - ) -> am::MapRange<'_, R>; + ) -> am::iter::MapRange<'a, R> + where + R: RangeBounds + 'a; fn list_range, R: RangeBounds>( &self, obj: O, range: R, - ) -> am::ListRange<'_, R>; + ) -> am::iter::ListRange<'_, R>; fn length>(&self, obj: O) -> usize; @@ -80,7 +82,7 @@ pub trait Doc: ReadDoc { &mut self, obj: O, pos: usize, - del: usize, + del: isize, text: &str, ) -> Result<(), AutomergeError>; } @@ -105,11 +107,14 @@ impl ReadDoc for am::AutoCommit { .unwrap_or(None) } - fn map_range, R: RangeBounds>( - &self, + fn map_range<'a, O: AsRef, R: RangeBounds>( + &'a self, obj: O, range: R, - ) -> am::MapRange<'_, R> { + ) -> am::iter::MapRange<'a, R> + where + R: RangeBounds + 'a, + { am::ReadDoc::map_range(self, obj, range) } @@ -117,7 +122,7 @@ impl ReadDoc for am::AutoCommit { &self, obj: O, range: R, - ) -> am::ListRange<'_, R> { + ) -> am::iter::ListRange<'_, R> { am::ReadDoc::list_range(self, obj, range) } @@ -134,7 +139,7 @@ impl ReadDoc for am::AutoCommit { } } -impl<'a, Obs: am::transaction::Observation> ReadDoc for am::transaction::Transaction<'a, Obs> { +impl<'a> ReadDoc for am::transaction::Transaction<'a> { type Parents<'b> = am::Parents<'b> where Self: 'b; fn get_heads(&self) -> Vec { am::transaction::Transactable::base_heads(self) @@ -154,11 +159,10 @@ impl<'a, Obs: am::transaction::Observation> ReadDoc for am::transaction::Transac .unwrap_or(None) } - fn map_range, R: RangeBounds>( - &self, - obj: O, - range: R, - ) -> am::MapRange<'_, R> { + fn map_range<'b, O: AsRef, R>(&'b self, obj: O, range: R) -> am::iter::MapRange<'b, R> + where + R: RangeBounds + 'b, + { am::ReadDoc::map_range(self, obj, range) } @@ -166,7 +170,7 @@ impl<'a, Obs: am::transaction::Observation> ReadDoc for am::transaction::Transac &self, obj: O, range: R, - ) -> am::ListRange<'_, R> { + ) -> am::iter::ListRange<'_, R> { am::ReadDoc::list_range(self, obj, range) } @@ -203,11 +207,11 @@ impl ReadDoc for am::Automerge { .unwrap_or(None) } - fn map_range, R: RangeBounds>( - &self, + fn map_range<'a, O: AsRef, R: RangeBounds + 'a>( + &'a self, obj: O, range: R, - ) -> am::MapRange<'_, R> { + ) -> am::iter::MapRange<'a, R> { am::ReadDoc::map_range(self, obj, range) } @@ -215,7 +219,7 @@ impl ReadDoc for am::Automerge { &self, obj: O, range: R, - ) -> am::ListRange<'_, R> { + ) -> am::iter::ListRange<'_, R> { am::ReadDoc::list_range(self, obj, range) } @@ -290,7 +294,7 @@ impl Doc for T { &mut self, obj: O, pos: usize, - del: usize, + del: isize, text: &str, ) -> Result<(), AutomergeError> { am::transaction::Transactable::splice_text(self, obj, pos, del, text) diff --git a/autosurgeon/src/hydrate/map.rs b/autosurgeon/src/hydrate/map.rs index 083139e..ac3861f 100644 --- a/autosurgeon/src/hydrate/map.rs +++ b/autosurgeon/src/hydrate/map.rs @@ -3,7 +3,7 @@ use std::{ hash::Hash, }; -use automerge::ObjType; +use automerge::{self as am, ObjType}; use crate::{Hydrate, HydrateError}; @@ -50,7 +50,7 @@ where match obj_type { ObjType::Map | ObjType::Table => doc .map_range(obj.clone(), ..) - .map(move |(key, _, _)| { + .map(move |am::iter::MapRangeItem { key, .. }| { let val = V::hydrate(doc, obj, key.into())?; let key_parsed: K = extract_key(key)?; Ok((key_parsed, val)) diff --git a/autosurgeon/src/reconcile.rs b/autosurgeon/src/reconcile.rs index d62db9c..81ef82f 100644 --- a/autosurgeon/src/reconcile.rs +++ b/autosurgeon/src/reconcile.rs @@ -215,7 +215,7 @@ pub trait TextReconciler { fn splice>( &mut self, pos: usize, - delete: usize, + delete: isize, insert: S, ) -> Result<(), Self::Error>; fn heads(&self) -> &[automerge::ChangeHash]; @@ -748,14 +748,16 @@ impl<'a, D: Doc> MapReconciler for InMap<'a, D> { } struct InMapEntries<'a> { - map_range: automerge::MapRange<'a, RangeFull>, + map_range: automerge::iter::MapRange<'a, RangeFull>, } impl<'a> Iterator for InMapEntries<'a> { type Item = (&'a str, automerge::Value<'a>); fn next(&mut self) -> Option { - self.map_range.next().map(|(key, val, _)| (key, val)) + self.map_range + .next() + .map(|automerge::iter::MapRangeItem { key, value, .. }| (key, value)) } } @@ -766,14 +768,14 @@ struct InSeq<'a, D> { } struct ItemsInSeq<'a> { - list_range: automerge::ListRange<'a, RangeFull>, + list_range: automerge::iter::ListRange<'a, RangeFull>, } impl<'a> Iterator for ItemsInSeq<'a> { type Item = automerge::Value<'a>; fn next(&mut self) -> Option { - self.list_range.next().map(|i| i.1) + self.list_range.next().map(|i| i.value) } } @@ -848,7 +850,7 @@ impl<'a, D: Doc> TextReconciler for InText<'a, D> { fn splice>( &mut self, pos: usize, - delete: usize, + delete: isize, text: S, ) -> Result<(), Self::Error> { self.doc diff --git a/autosurgeon/src/text.rs b/autosurgeon/src/text.rs index 50a6cb4..1bee11e 100644 --- a/autosurgeon/src/text.rs +++ b/autosurgeon/src/text.rs @@ -75,7 +75,8 @@ impl Text { /// # Arguments /// /// * pos - The index to start the splice at - /// * del - The number of characters to delete + /// * del - The number of characters to delete. This can be negative to indicate deleting `del` + /// characters preceding `pos` /// * insert - The characters to insert /// /// The `pos` index uses the same logic as [`String::replace_range`]. This means @@ -97,11 +98,18 @@ impl Text { /// value.splice(i, 0, "amazing "); /// assert_eq!(value.as_str(), "some amazing value"); /// ``` - pub fn splice>(&mut self, pos: usize, del: usize, insert: S) { + pub fn splice>(&mut self, pos: usize, del: isize, insert: S) { + let start = if del < 0 { + pos.saturating_sub(del.unsigned_abs()) + } else { + pos + }; match &mut self.0 { - State::Fresh(v) => v.replace_range(pos..(pos + del), insert.as_ref()), + State::Fresh(v) => { + v.replace_range(start..(start + del.unsigned_abs()), insert.as_ref()) + } State::Rehydrated { value, edits, .. } => { - value.replace_range(pos..(pos + del), insert.as_ref()); + value.replace_range(start..(start + del.unsigned_abs()), insert.as_ref()); edits.push(Splice { pos, delete: del, @@ -138,7 +146,7 @@ enum State { #[derive(Clone)] struct Splice { pos: usize, - delete: usize, + delete: isize, insert: String, }