diff --git a/Cargo.toml b/Cargo.toml index 292cf57..3616ebc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "reconcile-text" description = "Intelligent 3-way text merging with automated conflict resolution" version = "0.8.0" -rust-version = "1.85" +rust-version = "1.94" authors = ["Andras Schmelczer "] edition = "2024" license = "MIT" @@ -69,7 +69,7 @@ missing_debug_implementations = "warn" [lints.clippy] await_holding_lock = "warn" dbg_macro = "warn" -empty_enum = "warn" +empty_enums = "warn" enum_glob_use = "warn" exit = "warn" filter_map_next = "warn" diff --git a/reconcile-python/Cargo.toml b/reconcile-python/Cargo.toml index 48ab072..0f8d7e1 100644 --- a/reconcile-python/Cargo.toml +++ b/reconcile-python/Cargo.toml @@ -2,7 +2,7 @@ name = "reconcile-text-python" version = "0.8.0" edition = "2024" -rust-version = "1.85" +rust-version = "1.94" authors = ["Andras Schmelczer "] license = "MIT" publish = false diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 0d5c610..d9db229 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2025-06-06" +channel = "1.94.0" targets = [ "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl" ] profile = "default" diff --git a/rustfmt.toml b/rustfmt.toml index 6640f54..8a1751f 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,8 +1 @@ -imports_granularity = "crate" -condense_wildcard_suffixes = true -fn_single_line = true -format_strings = true -reorder_impl_items = true -group_imports = "StdExternalCrate" use_field_init_shorthand = true -wrap_comments=true diff --git a/src/operation_transformation/operation.rs b/src/operation_transformation/operation.rs index 9d06639..a6e2522 100644 --- a/src/operation_transformation/operation.rs +++ b/src/operation_transformation/operation.rs @@ -331,7 +331,7 @@ where order: last_equal_order, length: last_equal_length, #[cfg(debug_assertions)] - text: last_equal_text, + text: last_equal_text, .. }), ) => { @@ -342,7 +342,8 @@ where // matching (order, length) means they cover the same substring #[cfg(debug_assertions)] debug_assert_eq!( - text, last_equal_text, + text, + last_equal_text, "Equal operations with same order and length should have the same text, \ but got {operation:?} vs {:?}", Operation::::Equal { @@ -438,7 +439,9 @@ impl Debug for Operation where T: PartialEq + Clone + Debug, { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{self}") } + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{self}") + } } #[cfg(test)] diff --git a/src/raw_operation.rs b/src/raw_operation.rs index bde18c9..331ae81 100644 --- a/src/raw_operation.rs +++ b/src/raw_operation.rs @@ -20,7 +20,9 @@ impl RawOperation where T: PartialEq + Clone + Debug, { - pub fn vec_from(left: &[Token], right: &[Token]) -> Vec { myers_diff(left, right) } + pub fn vec_from(left: &[Token], right: &[Token]) -> Vec { + myers_diff(left, right) + } pub fn tokens(&self) -> &[Token] { match self { diff --git a/src/tokenizer/snapshots/reconcile_text__tokenizer__line_tokenizer__tests__with_snapshots-11.snap.new b/src/tokenizer/snapshots/reconcile_text__tokenizer__line_tokenizer__tests__with_snapshots-11.snap similarity index 97% rename from src/tokenizer/snapshots/reconcile_text__tokenizer__line_tokenizer__tests__with_snapshots-11.snap.new rename to src/tokenizer/snapshots/reconcile_text__tokenizer__line_tokenizer__tests__with_snapshots-11.snap index 36f12f9..c48bca5 100644 --- a/src/tokenizer/snapshots/reconcile_text__tokenizer__line_tokenizer__tests__with_snapshots-11.snap.new +++ b/src/tokenizer/snapshots/reconcile_text__tokenizer__line_tokenizer__tests__with_snapshots-11.snap @@ -1,6 +1,5 @@ --- source: src/tokenizer/line_tokenizer.rs -assertion_line: 78 expression: "line_tokenizer(\"Mixed\\r\\nand\\rbare\")" --- [ diff --git a/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-2.snap.new b/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-2.snap similarity index 96% rename from src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-2.snap.new rename to src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-2.snap index 0f35315..e255319 100644 --- a/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-2.snap.new +++ b/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-2.snap @@ -1,6 +1,5 @@ --- source: src/tokenizer/markdown_tokenizer.rs -assertion_line: 199 expression: "markdown_tokenizer(\"## Sub heading\")" --- [ diff --git a/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-3.snap b/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-3.snap new file mode 100644 index 0000000..aa4387c --- /dev/null +++ b/src/tokenizer/snapshots/reconcile_text__tokenizer__markdown_tokenizer__tests__headings-3.snap @@ -0,0 +1,24 @@ +--- +source: src/tokenizer/markdown_tokenizer.rs +expression: "markdown_tokenizer(\"###### Deep heading\")" +--- +[ + Token { + normalized: "###### Deep", + original: "###### Deep", + is_left_joinable: false, + is_right_joinable: true, + }, + Token { + normalized: " heading", + original: " ", + is_left_joinable: true, + is_right_joinable: true, + }, + Token { + normalized: "heading", + original: "heading", + is_left_joinable: true, + is_right_joinable: true, + }, +] diff --git a/src/tokenizer/token.rs b/src/tokenizer/token.rs index 5346717..5d82eb5 100644 --- a/src/tokenizer/token.rs +++ b/src/tokenizer/token.rs @@ -30,7 +30,9 @@ where /// Trivial implementation of Token when the normalized form is the same as the /// original string impl From<&str> for Token { - fn from(text: &str) -> Self { Token::new(text.to_owned(), text.to_owned(), true, true) } + fn from(text: &str) -> Self { + Token::new(text.to_owned(), text.to_owned(), true, true) + } } impl Token @@ -51,18 +53,28 @@ where } } - pub fn original(&self) -> &str { &self.original } + pub fn original(&self) -> &str { + &self.original + } - pub fn set_normalized(&mut self, normalized: T) { self.normalized = normalized; } + pub fn set_normalized(&mut self, normalized: T) { + self.normalized = normalized; + } - pub fn normalized(&self) -> &T { &self.normalized } + pub fn normalized(&self) -> &T { + &self.normalized + } - pub fn get_original_length(&self) -> usize { self.original.chars().count() } + pub fn get_original_length(&self) -> usize { + self.original.chars().count() + } } impl PartialEq for Token where T: PartialEq + Clone + Debug, { - fn eq(&self, other: &Self) -> bool { self.normalized == other.normalized } + fn eq(&self, other: &Self) -> bool { + self.normalized == other.normalized + } } diff --git a/src/types/cursor_position.rs b/src/types/cursor_position.rs index d69a1b2..c109b5d 100644 --- a/src/types/cursor_position.rs +++ b/src/types/cursor_position.rs @@ -18,7 +18,9 @@ pub struct CursorPosition { impl CursorPosition { #[cfg_attr(feature = "wasm", wasm_bindgen(constructor))] #[must_use] - pub fn new(id: usize, char_index: usize) -> Self { Self { id, char_index } } + pub fn new(id: usize, char_index: usize) -> Self { + Self { id, char_index } + } #[must_use] pub fn with_index(&self, index: usize) -> Self { @@ -29,9 +31,13 @@ impl CursorPosition { } #[must_use] - pub fn id(&self) -> usize { self.id } + pub fn id(&self) -> usize { + self.id + } #[cfg_attr(feature = "wasm", wasm_bindgen(js_name = characterIndex))] #[must_use] - pub fn char_index(&self) -> usize { self.char_index } + pub fn char_index(&self) -> usize { + self.char_index + } } diff --git a/src/types/number_or_text.rs b/src/types/number_or_text.rs index fe17af4..63b7a18 100644 --- a/src/types/number_or_text.rs +++ b/src/types/number_or_text.rs @@ -62,19 +62,27 @@ impl From for JsValue { } impl From for NumberOrText { - fn from(value: i64) -> Self { NumberOrText::Number(value) } + fn from(value: i64) -> Self { + NumberOrText::Number(value) + } } impl From for NumberOrText { - fn from(value: String) -> Self { NumberOrText::Text(value) } + fn from(value: String) -> Self { + NumberOrText::Text(value) + } } impl From<&str> for NumberOrText { - fn from(value: &str) -> Self { NumberOrText::Text(value.to_owned()) } + fn from(value: &str) -> Self { + NumberOrText::Text(value.to_owned()) + } } impl<'a> From> for NumberOrText { - fn from(value: Cow<'a, str>) -> Self { NumberOrText::Text(value.into_owned()) } + fn from(value: Cow<'a, str>) -> Self { + NumberOrText::Text(value.into_owned()) + } } /// Error type for deserialisation failures @@ -105,5 +113,7 @@ impl std::error::Error for DeserialisationError {} #[cfg(feature = "wasm")] impl From for JsValue { - fn from(error: DeserialisationError) -> Self { JsValue::from_str(&error.message) } + fn from(error: DeserialisationError) -> Self { + JsValue::from_str(&error.message) + } } diff --git a/src/types/span_with_history.rs b/src/types/span_with_history.rs index 7dafa81..1481218 100644 --- a/src/types/span_with_history.rs +++ b/src/types/span_with_history.rs @@ -18,11 +18,17 @@ pub struct SpanWithHistory { #[cfg_attr(feature = "wasm", wasm_bindgen)] impl SpanWithHistory { #[must_use] - pub fn new(text: String, history: History) -> Self { SpanWithHistory { text, history } } + pub fn new(text: String, history: History) -> Self { + SpanWithHistory { text, history } + } #[must_use] - pub fn history(&self) -> History { self.history } + pub fn history(&self) -> History { + self.history + } #[must_use] - pub fn text(&self) -> String { self.text.clone() } + pub fn text(&self) -> String { + self.text.clone() + } } diff --git a/src/types/text_with_cursors.rs b/src/types/text_with_cursors.rs index f58a34e..d796335 100644 --- a/src/types/text_with_cursors.rs +++ b/src/types/text_with_cursors.rs @@ -33,15 +33,21 @@ impl TextWithCursors { } #[must_use] - pub fn text(&self) -> String { self.text.to_string() } + pub fn text(&self) -> String { + self.text.clone() + } #[must_use] - pub fn cursors(&self) -> Vec { self.cursors.clone() } + pub fn cursors(&self) -> Vec { + self.cursors.clone() + } } impl TextWithCursors { #[must_use] - pub fn text_ref(&self) -> &str { &self.text } + pub fn text_ref(&self) -> &str { + &self.text + } } impl<'a> From<&'a str> for TextWithCursors { diff --git a/src/utils/myers_diff.rs b/src/utils/myers_diff.rs index dd9f961..b9a8b25 100644 --- a/src/utils/myers_diff.rs +++ b/src/utils/myers_diff.rs @@ -94,7 +94,9 @@ impl V { } } - fn len(&self) -> usize { self.v.len() } + fn len(&self) -> usize { + self.v.len() + } } impl Index for V { diff --git a/src/utils/string_builder.rs b/src/utils/string_builder.rs index abe372c..3fe42c3 100644 --- a/src/utils/string_builder.rs +++ b/src/utils/string_builder.rs @@ -35,7 +35,9 @@ impl StringBuilder<'_> { } /// Insert a string at the end of the built buffer - pub fn insert(&mut self, text: &str) { self.buffer.push_str(text); } + pub fn insert(&mut self, text: &str) { + self.buffer.push_str(text); + } /// Skip copying `length` characters from the original string to the built /// buffer @@ -64,7 +66,9 @@ impl StringBuilder<'_> { /// Returns the currently built buffer and clears it to allow consuming /// the result incrementally. - pub fn take(&mut self) -> String { std::mem::take(&mut self.buffer) } + pub fn take(&mut self) -> String { + std::mem::take(&mut self.buffer) + } /// Get a slice of the remaining original string. The slice starts from /// where the next delete/retain operation would start and is of length diff --git a/src/wasm.rs b/src/wasm.rs index c15a97f..06cccbe 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -139,13 +139,19 @@ pub struct TextWithCursorsAndHistory { #[wasm_bindgen] impl TextWithCursorsAndHistory { #[must_use] - pub fn text(&self) -> String { self.text_with_cursors.text() } + pub fn text(&self) -> String { + self.text_with_cursors.text() + } #[must_use] - pub fn cursors(&self) -> Vec { self.text_with_cursors.cursors() } + pub fn cursors(&self) -> Vec { + self.text_with_cursors.cursors() + } #[must_use] - pub fn history(&self) -> Vec { self.history.clone() } + pub fn history(&self) -> Vec { + self.history.clone() + } } /// Returns the UTF8 parsed string if it's a text, or `None` if it's likely diff --git a/tests/example_document.rs b/tests/example_document.rs index 6d8f370..b16cd44 100644 --- a/tests/example_document.rs +++ b/tests/example_document.rs @@ -18,7 +18,9 @@ pub struct ExampleDocument { impl ExampleDocument { #[must_use] - pub fn parent(&self) -> String { self.parent.clone() } + pub fn parent(&self) -> String { + self.parent.clone() + } #[must_use] pub fn left(&self) -> TextWithCursors {