| // This file is part of ICU4X. For terms of use, please see the file | ||
| // called LICENSE at the top level of the ICU4X source tree | ||
| // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
| use crate::Writeable; | ||
| use alloc::borrow::Cow; | ||
| use alloc::string::String; | ||
| use core::fmt; | ||
| /// Bytes that have been partially validated as UTF-8 up to an offset. | ||
| struct PartiallyValidatedUtf8<'a> { | ||
| // Safety Invariants: | ||
| // 1. The offset is less than or equal to the length of the slice. | ||
| // 2. The slice is valid UTF-8 up to the offset. | ||
| slice: &'a [u8], | ||
| offset: usize, | ||
| } | ||
| impl<'a> PartiallyValidatedUtf8<'a> { | ||
| fn new(slice: &'a [u8]) -> Self { | ||
| // Safety: Field invariants maintained here trivially: | ||
| // 1. The offset 0 is ≤ all possible lengths of slice | ||
| // 2. The slice contains nothing up to the offset zero | ||
| Self { slice, offset: 0 } | ||
| } | ||
| /// Check whether the given string is the next chunk of unvalidated bytes. | ||
| /// If so, increment offset and return true. Otherwise, return false. | ||
| fn try_push(&mut self, valid_str: &str) -> bool { | ||
| let new_offset = self.offset + valid_str.len(); | ||
| if self.slice.get(self.offset..new_offset) == Some(valid_str.as_bytes()) { | ||
| // Safety: Field invariants maintained here: | ||
| // 1. In the line above, `self.slice.get()` returned `Some()` for `new_offset` at | ||
| // the end of a `Range`, so `new_offset` is ≤ the length of `self.slice`. | ||
| // 2. By invariant, we have already validated the string up to `self.offset`, and | ||
| // the portion of the slice between `self.offset` and `new_offset` is equal to | ||
| // `valid_str`, which is a `&str`, so the string is valid up to `new_offset`. | ||
| self.offset = new_offset; | ||
| true | ||
| } else { | ||
| false | ||
| } | ||
| } | ||
| /// Return the validated portion as `&str`. | ||
| fn validated_as_str(&self) -> &'a str { | ||
| debug_assert!(self.offset <= self.slice.len()); | ||
| // Safety: self.offset is a valid end index in a range (from field invariant) | ||
| let valid_slice = unsafe { self.slice.get_unchecked(..self.offset) }; | ||
| debug_assert!(core::str::from_utf8(valid_slice).is_ok()); | ||
| // Safety: the UTF-8 of slice has been validated up to offset (from field invariant) | ||
| unsafe { core::str::from_utf8_unchecked(valid_slice) } | ||
| } | ||
| } | ||
| enum SliceOrString<'a> { | ||
| Slice(PartiallyValidatedUtf8<'a>), | ||
| String(String), | ||
| } | ||
| /// This is an infallible impl. Functions always return Ok, not Err. | ||
| impl fmt::Write for SliceOrString<'_> { | ||
| #[inline] | ||
| fn write_str(&mut self, other: &str) -> fmt::Result { | ||
| match self { | ||
| SliceOrString::Slice(slice) => { | ||
| if !slice.try_push(other) { | ||
| // We failed to match. Convert to owned. | ||
| let valid_str = slice.validated_as_str(); | ||
| let mut owned = String::with_capacity(valid_str.len() + other.len()); | ||
| owned.push_str(valid_str); | ||
| owned.push_str(other); | ||
| *self = SliceOrString::String(owned); | ||
| } | ||
| Ok(()) | ||
| } | ||
| SliceOrString::String(owned) => owned.write_str(other), | ||
| } | ||
| } | ||
| } | ||
| impl<'a> SliceOrString<'a> { | ||
| #[inline] | ||
| fn new(slice: &'a [u8]) -> Self { | ||
| Self::Slice(PartiallyValidatedUtf8::new(slice)) | ||
| } | ||
| #[inline] | ||
| fn finish(self) -> Cow<'a, str> { | ||
| match self { | ||
| SliceOrString::Slice(slice) => Cow::Borrowed(slice.validated_as_str()), | ||
| SliceOrString::String(owned) => Cow::Owned(owned), | ||
| } | ||
| } | ||
| } | ||
| /// Writes the contents of a `Writeable` to a string, returning a reference | ||
| /// to a slice if it matches the provided reference bytes, and allocating a | ||
| /// String otherwise. | ||
| /// | ||
| /// This function is useful if you have borrowed bytes which you expect | ||
| /// to be equal to a writeable a high percentage of the time. | ||
| /// | ||
| /// You can also use this function to make a more efficient implementation of | ||
| /// [`Writeable::write_to_string`]. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// Basic usage and behavior: | ||
| /// | ||
| /// ``` | ||
| /// use std::fmt; | ||
| /// use std::borrow::Cow; | ||
| /// use writeable::Writeable; | ||
| /// | ||
| /// struct WelcomeMessage<'s> { | ||
| /// pub name: &'s str, | ||
| /// } | ||
| /// | ||
| /// impl<'s> Writeable for WelcomeMessage<'s> { | ||
| /// // see impl in Writeable docs | ||
| /// # fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| /// # sink.write_str("Hello, ")?; | ||
| /// # sink.write_str(self.name)?; | ||
| /// # sink.write_char('!')?; | ||
| /// # Ok(()) | ||
| /// # } | ||
| /// } | ||
| /// | ||
| /// let message = WelcomeMessage { name: "Alice" }; | ||
| /// | ||
| /// assert!(matches!( | ||
| /// writeable::to_string_or_borrow(&message, b""), | ||
| /// Cow::Owned(s) if s == "Hello, Alice!" | ||
| /// )); | ||
| /// assert!(matches!( | ||
| /// writeable::to_string_or_borrow(&message, b"Hello"), | ||
| /// Cow::Owned(s) if s == "Hello, Alice!" | ||
| /// )); | ||
| /// assert!(matches!( | ||
| /// writeable::to_string_or_borrow(&message, b"Hello, Bob!"), | ||
| /// Cow::Owned(s) if s == "Hello, Alice!" | ||
| /// )); | ||
| /// assert!(matches!( | ||
| /// writeable::to_string_or_borrow(&message, b"Hello, Alice!"), | ||
| /// Cow::Borrowed("Hello, Alice!") | ||
| /// )); | ||
| /// | ||
| /// // Borrowing can use a prefix: | ||
| /// assert!(matches!( | ||
| /// writeable::to_string_or_borrow(&message, b"Hello, Alice!..\xFF\x00\xFF"), | ||
| /// Cow::Borrowed("Hello, Alice!") | ||
| /// )); | ||
| /// ``` | ||
| /// | ||
| /// Example use case: a function that transforms a string to lowercase. | ||
| /// We are also able to write a more efficient implementation of | ||
| /// [`Writeable::write_to_string`] in this situation. | ||
| /// | ||
| /// ``` | ||
| /// use std::fmt; | ||
| /// use std::borrow::Cow; | ||
| /// use writeable::Writeable; | ||
| /// | ||
| /// struct MakeAsciiLower<'a>(&'a str); | ||
| /// | ||
| /// impl<'a> Writeable for MakeAsciiLower<'a> { | ||
| /// fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| /// for c in self.0.chars() { | ||
| /// sink.write_char(c.to_ascii_lowercase())?; | ||
| /// } | ||
| /// Ok(()) | ||
| /// } | ||
| /// #[inline] | ||
| /// fn write_to_string(&self) -> Cow<str> { | ||
| /// writeable::to_string_or_borrow(self, self.0.as_bytes()) | ||
| /// } | ||
| /// } | ||
| /// | ||
| /// fn make_lowercase(input: &str) -> Cow<str> { | ||
| /// let writeable = MakeAsciiLower(input); | ||
| /// writeable::to_string_or_borrow(&writeable, input.as_bytes()) | ||
| /// } | ||
| /// | ||
| /// assert!(matches!( | ||
| /// make_lowercase("this is lowercase"), | ||
| /// Cow::Borrowed("this is lowercase") | ||
| /// )); | ||
| /// assert!(matches!( | ||
| /// make_lowercase("this is UPPERCASE"), | ||
| /// Cow::Owned(s) if s == "this is uppercase" | ||
| /// )); | ||
| /// | ||
| /// assert!(matches!( | ||
| /// MakeAsciiLower("this is lowercase").write_to_string(), | ||
| /// Cow::Borrowed("this is lowercase") | ||
| /// )); | ||
| /// assert!(matches!( | ||
| /// MakeAsciiLower("this is UPPERCASE").write_to_string(), | ||
| /// Cow::Owned(s) if s == "this is uppercase" | ||
| /// )); | ||
| /// ``` | ||
| pub fn to_string_or_borrow<'a>( | ||
| writeable: &impl Writeable, | ||
| reference_bytes: &'a [u8], | ||
| ) -> Cow<'a, str> { | ||
| let mut sink = SliceOrString::new(reference_bytes); | ||
| let _ = writeable.write_to(&mut sink); | ||
| sink.finish() | ||
| } |
| { | ||
| "git": { | ||
| "sha1": "55cd12ebb25c6261492e1e3dfa2e6453c54dde31" | ||
| "sha1": "6bd4893cc44c2ca2718de47a119a31cc40045fe5" | ||
| }, | ||
| "path_in_vcs": "utils/writeable" | ||
| } |
+36
-0
@@ -28,2 +28,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| /// A sample type implementing Display | ||
| #[cfg(feature = "bench")] | ||
| struct DisplayMessage<'s> { | ||
@@ -33,2 +34,3 @@ message: &'s str, | ||
| #[cfg(feature = "bench")] | ||
| impl fmt::Display for DisplayMessage<'_> { | ||
@@ -41,2 +43,3 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| /// A sample type that contains multiple fields | ||
| #[cfg(feature = "bench")] | ||
| struct ComplexWriteable<'a> { | ||
@@ -50,2 +53,3 @@ prefix: &'a str, | ||
| #[cfg(feature = "bench")] | ||
| impl Writeable for ComplexWriteable<'_> { | ||
@@ -70,2 +74,3 @@ fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| #[cfg(feature = "bench")] | ||
| writeable::impl_display_with_writeable!(ComplexWriteable<'_>); | ||
@@ -76,2 +81,5 @@ | ||
| const LONG_STR: &str = "this string is very very very very very very very very very very very very very very very very very very very very very very very very long"; | ||
| #[cfg(feature = "bench")] | ||
| const LONG_OVERLAP_STR: &str = | ||
| "this string is very very very very very very very long but different"; | ||
@@ -135,2 +143,16 @@ fn overview_bench(c: &mut Criterion) { | ||
| }); | ||
| c.bench_function("writeable/cmp_str", |b| { | ||
| b.iter(|| { | ||
| let short = black_box(SHORT_STR); | ||
| let medium = black_box(MEDIUM_STR); | ||
| let long = black_box(LONG_STR); | ||
| let long_overlap = black_box(LONG_OVERLAP_STR); | ||
| [short, medium, long, long_overlap].map(|s1| { | ||
| [short, medium, long, long_overlap].map(|s2| { | ||
| let message = WriteableMessage { message: s1 }; | ||
| writeable::cmp_str(&message, s2) | ||
| }) | ||
| }) | ||
| }); | ||
| }); | ||
| } | ||
@@ -218,2 +240,16 @@ | ||
| }); | ||
| const REFERENCE_STRS: [&str; 6] = [ | ||
| "There are 55 apples and 8124 oranges", | ||
| "There are 55 apples and 0 oranges", | ||
| "There are no apples", | ||
| SHORT_STR, | ||
| MEDIUM_STR, | ||
| LONG_STR, | ||
| ]; | ||
| c.bench_function("complex/cmp_str", |b| { | ||
| b.iter(|| { | ||
| black_box(REFERENCE_STRS) | ||
| .map(|s| writeable::cmp_str(black_box(&COMPLEX_WRITEABLE_MEDIUM), s)) | ||
| }); | ||
| }); | ||
| } | ||
@@ -220,0 +256,0 @@ |
+197
-253
@@ -6,2 +6,11 @@ # This file is automatically @generated by Cargo. | ||
| [[package]] | ||
| name = "aho-corasick" | ||
| version = "1.1.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" | ||
| dependencies = [ | ||
| "memchr", | ||
| ] | ||
| [[package]] | ||
| name = "anes" | ||
@@ -13,24 +22,24 @@ version = "0.1.6" | ||
| [[package]] | ||
| name = "autocfg" | ||
| version = "1.1.0" | ||
| name = "anstyle" | ||
| version = "1.0.10" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" | ||
| checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" | ||
| [[package]] | ||
| name = "bitflags" | ||
| version = "1.3.2" | ||
| name = "autocfg" | ||
| version = "1.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" | ||
| checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" | ||
| [[package]] | ||
| name = "bitflags" | ||
| version = "2.4.2" | ||
| name = "bumpalo" | ||
| version = "3.15.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" | ||
| checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" | ||
| [[package]] | ||
| name = "bumpalo" | ||
| version = "3.14.0" | ||
| name = "byteorder" | ||
| version = "1.5.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" | ||
| checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" | ||
@@ -51,5 +60,5 @@ [[package]] | ||
| name = "ciborium" | ||
| version = "0.2.1" | ||
| version = "0.2.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" | ||
| checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" | ||
| dependencies = [ | ||
@@ -63,11 +72,11 @@ "ciborium-io", | ||
| name = "ciborium-io" | ||
| version = "0.2.1" | ||
| version = "0.2.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" | ||
| checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" | ||
| [[package]] | ||
| name = "ciborium-ll" | ||
| version = "0.2.1" | ||
| version = "0.2.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" | ||
| checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" | ||
| dependencies = [ | ||
@@ -80,5 +89,5 @@ "ciborium-io", | ||
| name = "clap" | ||
| version = "4.2.1" | ||
| version = "4.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" | ||
| checksum = "1d5f1946157a96594eb2d2c10eb7ad9a2b27518cb3000209dec700c35df9197d" | ||
| dependencies = [ | ||
@@ -90,7 +99,7 @@ "clap_builder", | ||
| name = "clap_builder" | ||
| version = "4.2.1" | ||
| version = "4.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" | ||
| checksum = "78116e32a042dd73c2901f0dc30790d20ff3447f3e3472fad359e8c3d282bcd6" | ||
| dependencies = [ | ||
| "bitflags 1.3.2", | ||
| "anstyle", | ||
| "clap_lex", | ||
@@ -101,5 +110,5 @@ ] | ||
| name = "clap_lex" | ||
| version = "0.4.1" | ||
| version = "0.5.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" | ||
| checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" | ||
@@ -144,7 +153,6 @@ [[package]] | ||
| name = "crossbeam-deque" | ||
| version = "0.8.3" | ||
| version = "0.8.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" | ||
| checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" | ||
| dependencies = [ | ||
| "cfg-if", | ||
| "crossbeam-epoch", | ||
@@ -156,11 +164,7 @@ "crossbeam-utils", | ||
| name = "crossbeam-epoch" | ||
| version = "0.9.15" | ||
| version = "0.9.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" | ||
| checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" | ||
| dependencies = [ | ||
| "autocfg", | ||
| "cfg-if", | ||
| "crossbeam-utils", | ||
| "memoffset", | ||
| "scopeguard", | ||
| ] | ||
@@ -170,27 +174,23 @@ | ||
| name = "crossbeam-utils" | ||
| version = "0.8.19" | ||
| version = "0.8.20" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" | ||
| checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" | ||
| [[package]] | ||
| name = "either" | ||
| version = "1.9.0" | ||
| name = "crunchy" | ||
| version = "0.2.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" | ||
| checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" | ||
| [[package]] | ||
| name = "errno" | ||
| version = "0.3.8" | ||
| name = "either" | ||
| version = "1.13.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" | ||
| dependencies = [ | ||
| "libc", | ||
| "windows-sys 0.52.0", | ||
| ] | ||
| checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" | ||
| [[package]] | ||
| name = "getrandom" | ||
| version = "0.2.10" | ||
| version = "0.2.15" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" | ||
| checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" | ||
| dependencies = [ | ||
@@ -204,21 +204,25 @@ "cfg-if", | ||
| name = "half" | ||
| version = "1.8.2" | ||
| version = "2.4.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" | ||
| checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" | ||
| dependencies = [ | ||
| "cfg-if", | ||
| "crunchy", | ||
| ] | ||
| [[package]] | ||
| name = "hermit-abi" | ||
| version = "0.3.3" | ||
| version = "0.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" | ||
| checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" | ||
| [[package]] | ||
| name = "is-terminal" | ||
| version = "0.4.9" | ||
| version = "0.4.13" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" | ||
| checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" | ||
| dependencies = [ | ||
| "hermit-abi", | ||
| "rustix", | ||
| "windows-sys 0.48.0", | ||
| "libc", | ||
| "windows-sys 0.52.0", | ||
| ] | ||
@@ -237,11 +241,11 @@ | ||
| name = "itoa" | ||
| version = "1.0.9" | ||
| version = "1.0.13" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" | ||
| checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" | ||
| [[package]] | ||
| name = "js-sys" | ||
| version = "0.3.64" | ||
| version = "0.3.72" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" | ||
| checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" | ||
| dependencies = [ | ||
@@ -253,32 +257,23 @@ "wasm-bindgen", | ||
| name = "libc" | ||
| version = "0.2.153" | ||
| version = "0.2.164" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" | ||
| checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" | ||
| [[package]] | ||
| name = "linux-raw-sys" | ||
| version = "0.4.13" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" | ||
| [[package]] | ||
| name = "log" | ||
| version = "0.4.20" | ||
| version = "0.4.22" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" | ||
| checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" | ||
| [[package]] | ||
| name = "memoffset" | ||
| version = "0.9.0" | ||
| name = "memchr" | ||
| version = "2.7.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" | ||
| dependencies = [ | ||
| "autocfg", | ||
| ] | ||
| checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" | ||
| [[package]] | ||
| name = "num-traits" | ||
| version = "0.2.18" | ||
| version = "0.2.19" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" | ||
| checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" | ||
| dependencies = [ | ||
@@ -290,17 +285,17 @@ "autocfg", | ||
| name = "once_cell" | ||
| version = "1.18.0" | ||
| version = "1.20.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" | ||
| checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" | ||
| [[package]] | ||
| name = "oorandom" | ||
| version = "11.1.3" | ||
| version = "11.1.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" | ||
| checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" | ||
| [[package]] | ||
| name = "plotters" | ||
| version = "0.3.5" | ||
| version = "0.3.7" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" | ||
| checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" | ||
| dependencies = [ | ||
@@ -316,11 +311,11 @@ "num-traits", | ||
| name = "plotters-backend" | ||
| version = "0.3.5" | ||
| version = "0.3.7" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" | ||
| checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" | ||
| [[package]] | ||
| name = "plotters-svg" | ||
| version = "0.3.5" | ||
| version = "0.3.7" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" | ||
| checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" | ||
| dependencies = [ | ||
@@ -332,11 +327,14 @@ "plotters-backend", | ||
| name = "ppv-lite86" | ||
| version = "0.2.17" | ||
| version = "0.2.20" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" | ||
| checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" | ||
| dependencies = [ | ||
| "zerocopy", | ||
| ] | ||
| [[package]] | ||
| name = "proc-macro2" | ||
| version = "1.0.82" | ||
| version = "1.0.92" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" | ||
| checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" | ||
| dependencies = [ | ||
@@ -348,5 +346,5 @@ "unicode-ident", | ||
| name = "quote" | ||
| version = "1.0.35" | ||
| version = "1.0.37" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" | ||
| checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" | ||
| dependencies = [ | ||
@@ -388,5 +386,5 @@ "proc-macro2", | ||
| name = "rayon" | ||
| version = "1.8.0" | ||
| version = "1.10.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" | ||
| checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" | ||
| dependencies = [ | ||
@@ -399,5 +397,5 @@ "either", | ||
| name = "rayon-core" | ||
| version = "1.12.0" | ||
| version = "1.12.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" | ||
| checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" | ||
| dependencies = [ | ||
@@ -410,6 +408,9 @@ "crossbeam-deque", | ||
| name = "regex" | ||
| version = "1.8.4" | ||
| version = "1.11.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" | ||
| checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" | ||
| dependencies = [ | ||
| "aho-corasick", | ||
| "memchr", | ||
| "regex-automata", | ||
| "regex-syntax", | ||
@@ -419,25 +420,23 @@ ] | ||
| [[package]] | ||
| name = "regex-syntax" | ||
| version = "0.7.5" | ||
| name = "regex-automata" | ||
| version = "0.4.9" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" | ||
| checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" | ||
| dependencies = [ | ||
| "aho-corasick", | ||
| "memchr", | ||
| "regex-syntax", | ||
| ] | ||
| [[package]] | ||
| name = "rustix" | ||
| version = "0.38.31" | ||
| name = "regex-syntax" | ||
| version = "0.8.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" | ||
| dependencies = [ | ||
| "bitflags 2.4.2", | ||
| "errno", | ||
| "libc", | ||
| "linux-raw-sys", | ||
| "windows-sys 0.52.0", | ||
| ] | ||
| checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" | ||
| [[package]] | ||
| name = "ryu" | ||
| version = "1.0.15" | ||
| version = "1.0.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" | ||
| checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" | ||
@@ -454,12 +453,6 @@ [[package]] | ||
| [[package]] | ||
| name = "scopeguard" | ||
| version = "1.2.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" | ||
| [[package]] | ||
| name = "serde" | ||
| version = "1.0.188" | ||
| version = "1.0.215" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" | ||
| checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" | ||
| dependencies = [ | ||
@@ -471,5 +464,5 @@ "serde_derive", | ||
| name = "serde_derive" | ||
| version = "1.0.188" | ||
| version = "1.0.215" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" | ||
| checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" | ||
| dependencies = [ | ||
@@ -483,7 +476,8 @@ "proc-macro2", | ||
| name = "serde_json" | ||
| version = "1.0.107" | ||
| version = "1.0.133" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" | ||
| checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" | ||
| dependencies = [ | ||
| "itoa", | ||
| "memchr", | ||
| "ryu", | ||
@@ -495,5 +489,5 @@ "serde", | ||
| name = "syn" | ||
| version = "2.0.58" | ||
| version = "2.0.89" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" | ||
| checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" | ||
| dependencies = [ | ||
@@ -517,11 +511,11 @@ "proc-macro2", | ||
| name = "unicode-ident" | ||
| version = "1.0.12" | ||
| version = "1.0.14" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" | ||
| checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" | ||
| [[package]] | ||
| name = "walkdir" | ||
| version = "2.4.0" | ||
| version = "2.5.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" | ||
| checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" | ||
| dependencies = [ | ||
@@ -540,7 +534,8 @@ "same-file", | ||
| name = "wasm-bindgen" | ||
| version = "0.2.87" | ||
| version = "0.2.95" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" | ||
| checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" | ||
| dependencies = [ | ||
| "cfg-if", | ||
| "once_cell", | ||
| "wasm-bindgen-macro", | ||
@@ -551,5 +546,5 @@ ] | ||
| name = "wasm-bindgen-backend" | ||
| version = "0.2.87" | ||
| version = "0.2.95" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" | ||
| checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" | ||
| dependencies = [ | ||
@@ -567,5 +562,5 @@ "bumpalo", | ||
| name = "wasm-bindgen-macro" | ||
| version = "0.2.87" | ||
| version = "0.2.95" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" | ||
| checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" | ||
| dependencies = [ | ||
@@ -578,5 +573,5 @@ "quote", | ||
| name = "wasm-bindgen-macro-support" | ||
| version = "0.2.87" | ||
| version = "0.2.95" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" | ||
| checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" | ||
| dependencies = [ | ||
@@ -592,11 +587,11 @@ "proc-macro2", | ||
| name = "wasm-bindgen-shared" | ||
| version = "0.2.87" | ||
| version = "0.2.95" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" | ||
| checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" | ||
| [[package]] | ||
| name = "web-sys" | ||
| version = "0.3.64" | ||
| version = "0.3.72" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" | ||
| checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" | ||
| dependencies = [ | ||
@@ -608,43 +603,12 @@ "js-sys", | ||
| [[package]] | ||
| name = "winapi" | ||
| version = "0.3.9" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" | ||
| dependencies = [ | ||
| "winapi-i686-pc-windows-gnu", | ||
| "winapi-x86_64-pc-windows-gnu", | ||
| ] | ||
| [[package]] | ||
| name = "winapi-i686-pc-windows-gnu" | ||
| version = "0.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" | ||
| [[package]] | ||
| name = "winapi-util" | ||
| version = "0.1.6" | ||
| version = "0.1.9" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" | ||
| checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" | ||
| dependencies = [ | ||
| "winapi", | ||
| "windows-sys 0.59.0", | ||
| ] | ||
| [[package]] | ||
| name = "winapi-x86_64-pc-windows-gnu" | ||
| version = "0.4.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" | ||
| [[package]] | ||
| name = "windows-sys" | ||
| version = "0.48.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" | ||
| dependencies = [ | ||
| "windows-targets 0.48.5", | ||
| ] | ||
| [[package]] | ||
| name = "windows-sys" | ||
| version = "0.52.0" | ||
@@ -654,18 +618,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| dependencies = [ | ||
| "windows-targets 0.52.0", | ||
| "windows-targets", | ||
| ] | ||
| [[package]] | ||
| name = "windows-targets" | ||
| version = "0.48.5" | ||
| name = "windows-sys" | ||
| version = "0.59.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" | ||
| checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" | ||
| dependencies = [ | ||
| "windows_aarch64_gnullvm 0.48.5", | ||
| "windows_aarch64_msvc 0.48.5", | ||
| "windows_i686_gnu 0.48.5", | ||
| "windows_i686_msvc 0.48.5", | ||
| "windows_x86_64_gnu 0.48.5", | ||
| "windows_x86_64_gnullvm 0.48.5", | ||
| "windows_x86_64_msvc 0.48.5", | ||
| "windows-targets", | ||
| ] | ||
@@ -675,13 +633,14 @@ | ||
| name = "windows-targets" | ||
| version = "0.52.0" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" | ||
| checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" | ||
| dependencies = [ | ||
| "windows_aarch64_gnullvm 0.52.0", | ||
| "windows_aarch64_msvc 0.52.0", | ||
| "windows_i686_gnu 0.52.0", | ||
| "windows_i686_msvc 0.52.0", | ||
| "windows_x86_64_gnu 0.52.0", | ||
| "windows_x86_64_gnullvm 0.52.0", | ||
| "windows_x86_64_msvc 0.52.0", | ||
| "windows_aarch64_gnullvm", | ||
| "windows_aarch64_msvc", | ||
| "windows_i686_gnu", | ||
| "windows_i686_gnullvm", | ||
| "windows_i686_msvc", | ||
| "windows_x86_64_gnu", | ||
| "windows_x86_64_gnullvm", | ||
| "windows_x86_64_msvc", | ||
| ] | ||
@@ -691,87 +650,51 @@ | ||
| name = "windows_aarch64_gnullvm" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" | ||
| checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" | ||
| [[package]] | ||
| name = "windows_aarch64_gnullvm" | ||
| version = "0.52.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" | ||
| [[package]] | ||
| name = "windows_aarch64_msvc" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" | ||
| checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" | ||
| [[package]] | ||
| name = "windows_aarch64_msvc" | ||
| version = "0.52.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" | ||
| [[package]] | ||
| name = "windows_i686_gnu" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" | ||
| checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" | ||
| [[package]] | ||
| name = "windows_i686_gnu" | ||
| version = "0.52.0" | ||
| name = "windows_i686_gnullvm" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" | ||
| checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" | ||
| [[package]] | ||
| name = "windows_i686_msvc" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" | ||
| checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" | ||
| [[package]] | ||
| name = "windows_i686_msvc" | ||
| version = "0.52.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" | ||
| [[package]] | ||
| name = "windows_x86_64_gnu" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" | ||
| checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" | ||
| [[package]] | ||
| name = "windows_x86_64_gnu" | ||
| version = "0.52.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" | ||
| [[package]] | ||
| name = "windows_x86_64_gnullvm" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" | ||
| checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" | ||
| [[package]] | ||
| name = "windows_x86_64_gnullvm" | ||
| version = "0.52.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" | ||
| [[package]] | ||
| name = "windows_x86_64_msvc" | ||
| version = "0.48.5" | ||
| version = "0.52.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" | ||
| checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" | ||
| [[package]] | ||
| name = "windows_x86_64_msvc" | ||
| version = "0.52.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" | ||
| [[package]] | ||
| name = "writeable" | ||
| version = "0.5.5" | ||
| version = "0.6.0" | ||
| dependencies = [ | ||
@@ -782,1 +705,22 @@ "criterion", | ||
| ] | ||
| [[package]] | ||
| name = "zerocopy" | ||
| version = "0.7.35" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" | ||
| dependencies = [ | ||
| "byteorder", | ||
| "zerocopy-derive", | ||
| ] | ||
| [[package]] | ||
| name = "zerocopy-derive" | ||
| version = "0.7.35" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" | ||
| dependencies = [ | ||
| "proc-macro2", | ||
| "quote", | ||
| "syn", | ||
| ] |
+19
-3
@@ -14,6 +14,7 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| edition = "2021" | ||
| rust-version = "1.67" | ||
| rust-version = "1.71.1" | ||
| name = "writeable" | ||
| version = "0.5.5" | ||
| version = "0.6.0" | ||
| authors = ["The ICU4X Project Developers"] | ||
| build = false | ||
| include = [ | ||
@@ -29,2 +30,6 @@ "data/**/*", | ||
| ] | ||
| autobins = false | ||
| autoexamples = false | ||
| autotests = false | ||
| autobenches = false | ||
| description = "A more efficient alternative to fmt::Display" | ||
@@ -45,6 +50,17 @@ readme = "README.md" | ||
| [lib] | ||
| name = "writeable" | ||
| path = "src/lib.rs" | ||
| bench = false | ||
| [[example]] | ||
| name = "writeable_message" | ||
| path = "examples/writeable_message.rs" | ||
| [[test]] | ||
| name = "writeable" | ||
| path = "tests/writeable.rs" | ||
| [[bench]] | ||
| name = "writeable" | ||
| path = "benches/writeable.rs" | ||
| harness = false | ||
@@ -65,3 +81,3 @@ | ||
| [target."cfg(not(target_arch = \"wasm32\"))".dev-dependencies.criterion] | ||
| [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies.criterion] | ||
| version = "0.5.0" |
@@ -6,4 +6,6 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| // This example illustrates a very simple type implementing Writeable. | ||
| icu_benchmark_macros::static_setup!(); | ||
| #![no_main] // https://github.com/unicode-org/icu4x/issues/395 | ||
| icu_benchmark_macros::instrument!(); | ||
| use std::fmt; | ||
@@ -49,4 +51,2 @@ use writeable::*; | ||
| fn main() { | ||
| icu_benchmark_macros::main_setup!(); | ||
| let (string, parts) = | ||
@@ -53,0 +53,0 @@ writeable::_internal::writeable_to_parts_for_test(&WriteableMessage("world")); |
+1
-0
@@ -48,2 +48,3 @@ # writeable [](https://crates.io/crates/writeable) | ||
| writeable::impl_display_with_writeable!(WelcomeMessage<'_>); | ||
| assert_eq!(message.to_string(), "Hello, Alice!"); | ||
| ``` | ||
@@ -50,0 +51,0 @@ |
+68
-13
@@ -5,7 +5,8 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| use crate::Writeable; | ||
| use core::cmp::Ordering; | ||
| use core::fmt; | ||
| pub(crate) struct WriteComparator<'a> { | ||
| string: &'a [u8], | ||
| struct WriteComparator<'a> { | ||
| code_units: &'a [u8], | ||
| result: Ordering, | ||
@@ -15,3 +16,3 @@ } | ||
| /// This is an infallible impl. Functions always return Ok, not Err. | ||
| impl<'a> fmt::Write for WriteComparator<'a> { | ||
| impl fmt::Write for WriteComparator<'_> { | ||
| #[inline] | ||
@@ -22,5 +23,5 @@ fn write_str(&mut self, other: &str) -> fmt::Result { | ||
| } | ||
| let cmp_len = core::cmp::min(other.len(), self.string.len()); | ||
| let (this, remainder) = self.string.split_at(cmp_len); | ||
| self.string = remainder; | ||
| let cmp_len = core::cmp::min(other.len(), self.code_units.len()); | ||
| let (this, remainder) = self.code_units.split_at(cmp_len); | ||
| self.code_units = remainder; | ||
| self.result = this.cmp(other.as_bytes()); | ||
@@ -33,5 +34,5 @@ Ok(()) | ||
| #[inline] | ||
| pub fn new(string: &'a (impl AsRef<[u8]> + ?Sized)) -> Self { | ||
| fn new(code_units: &'a [u8]) -> Self { | ||
| Self { | ||
| string: string.as_ref(), | ||
| code_units, | ||
| result: Ordering::Equal, | ||
@@ -42,4 +43,4 @@ } | ||
| #[inline] | ||
| pub fn finish(self) -> Ordering { | ||
| if matches!(self.result, Ordering::Equal) && !self.string.is_empty() { | ||
| fn finish(self) -> Ordering { | ||
| if matches!(self.result, Ordering::Equal) && !self.code_units.is_empty() { | ||
| // Self is longer than Other | ||
@@ -53,2 +54,56 @@ Ordering::Greater | ||
| /// Compares the contents of a [`Writeable`] to the given UTF-8 bytes without allocating memory. | ||
| /// | ||
| /// For more details, see: [`cmp_str`] | ||
| pub fn cmp_utf8(writeable: &impl Writeable, other: &[u8]) -> Ordering { | ||
| let mut wc = WriteComparator::new(other); | ||
| let _ = writeable.write_to(&mut wc); | ||
| wc.finish().reverse() | ||
| } | ||
| /// Compares the contents of a `Writeable` to the given bytes | ||
| /// without allocating a String to hold the `Writeable` contents. | ||
| /// | ||
| /// This returns a lexicographical comparison, the same as if the Writeable | ||
| /// were first converted to a String and then compared with `Ord`. For a | ||
| /// string ordering suitable for display to end users, use a localized | ||
| /// collation crate, such as `icu_collator`. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use core::cmp::Ordering; | ||
| /// use core::fmt; | ||
| /// use writeable::Writeable; | ||
| /// | ||
| /// struct WelcomeMessage<'s> { | ||
| /// pub name: &'s str, | ||
| /// } | ||
| /// | ||
| /// impl<'s> Writeable for WelcomeMessage<'s> { | ||
| /// // see impl in Writeable docs | ||
| /// # fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| /// # sink.write_str("Hello, ")?; | ||
| /// # sink.write_str(self.name)?; | ||
| /// # sink.write_char('!')?; | ||
| /// # Ok(()) | ||
| /// # } | ||
| /// } | ||
| /// | ||
| /// let message = WelcomeMessage { name: "Alice" }; | ||
| /// let message_str = message.write_to_string(); | ||
| /// | ||
| /// assert_eq!(Ordering::Equal, writeable::cmp_str(&message, "Hello, Alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Greater, writeable::cmp_str(&message, "Alice!")); | ||
| /// assert_eq!(Ordering::Greater, (*message_str).cmp("Alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Less, writeable::cmp_str(&message, "Hello, Bob!")); | ||
| /// assert_eq!(Ordering::Less, (*message_str).cmp("Hello, Bob!")); | ||
| /// ``` | ||
| #[inline] | ||
| pub fn cmp_str(writeable: &impl Writeable, other: &str) -> Ordering { | ||
| cmp_utf8(writeable, other.as_bytes()) | ||
| } | ||
| #[cfg(test)] | ||
@@ -67,3 +122,3 @@ mod tests { | ||
| for b in data::KEBAB_CASE_STRINGS { | ||
| let mut wc = WriteComparator::new(a); | ||
| let mut wc = WriteComparator::new(a.as_bytes()); | ||
| for ch in b.chars() { | ||
@@ -81,3 +136,3 @@ wc.write_char(ch).unwrap(); | ||
| for b in data::KEBAB_CASE_STRINGS { | ||
| let mut wc = WriteComparator::new(a); | ||
| let mut wc = WriteComparator::new(a.as_bytes()); | ||
| wc.write_str(b).unwrap(); | ||
@@ -93,3 +148,3 @@ assert_eq!(a.cmp(b), wc.finish(), "{a} <=> {b}"); | ||
| for b in data::KEBAB_CASE_STRINGS { | ||
| let mut wc = WriteComparator::new(a); | ||
| let mut wc = WriteComparator::new(a.as_bytes()); | ||
| let mut first = true; | ||
@@ -96,0 +151,0 @@ for substr in b.split('-') { |
+0
-7
@@ -41,9 +41,2 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| } | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| match self { | ||
| Either::Left(w) => w.writeable_cmp_bytes(other), | ||
| Either::Right(w) => w.writeable_cmp_bytes(other), | ||
| } | ||
| } | ||
| } |
+1
-25
@@ -118,7 +118,2 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| self.as_bytes().cmp(other) | ||
| } | ||
| } | ||
@@ -141,7 +136,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| self.as_bytes().cmp(other) | ||
| } | ||
| } | ||
@@ -166,7 +156,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| self.encode_utf8(&mut [0u8; 4]).as_bytes().cmp(other) | ||
| } | ||
| } | ||
@@ -194,7 +179,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| (*self).writeable_cmp_bytes(other) | ||
| } | ||
| } | ||
@@ -221,6 +201,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| core::borrow::Borrow::<T>::borrow(self).writeable_cmp_bytes(other) | ||
| } | ||
| } | ||
@@ -263,3 +239,3 @@ }; | ||
| assert_eq!( | ||
| chars[j].writeable_cmp_bytes(s.as_bytes()), | ||
| crate::cmp_str(&chars[j], &s), | ||
| chars[j].cmp(&chars[i]), | ||
@@ -266,0 +242,0 @@ "{:?} vs {:?}", |
+52
-59
@@ -63,2 +63,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| //! writeable::impl_display_with_writeable!(WelcomeMessage<'_>); | ||
| //! assert_eq!(message.to_string(), "Hello, Alice!"); | ||
| //! ``` | ||
@@ -77,2 +78,3 @@ //! | ||
| mod testing; | ||
| mod to_string_or_borrow; | ||
| mod try_writeable; | ||
@@ -84,2 +86,4 @@ | ||
| pub use cmp::{cmp_str, cmp_utf8}; | ||
| pub use to_string_or_borrow::to_string_or_borrow; | ||
| pub use try_writeable::TryWriteable; | ||
@@ -92,10 +96,34 @@ | ||
| pub use parts_write_adapter::CoreWriteAsPartsWrite; | ||
| pub use parts_write_adapter::WithPart; | ||
| pub use try_writeable::TryWriteableInfallibleAsWriteable; | ||
| pub use try_writeable::WriteableAsTryWriteableInfallible; | ||
| #[derive(Debug)] | ||
| #[allow(clippy::exhaustive_structs)] // newtype | ||
| pub struct LossyWrap<T>(pub T); | ||
| impl<T: TryWriteable> Writeable for LossyWrap<T> { | ||
| fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| let _ = self.0.try_write_to(sink)?; | ||
| Ok(()) | ||
| } | ||
| fn writeable_length_hint(&self) -> LengthHint { | ||
| self.0.writeable_length_hint() | ||
| } | ||
| } | ||
| impl<T: TryWriteable> fmt::Display for LossyWrap<T> { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| let _ = self.0.try_write_to(f)?; | ||
| Ok(()) | ||
| } | ||
| } | ||
| } | ||
| #[doc(hidden)] | ||
| #[doc(hidden)] // for testing and macros | ||
| pub mod _internal { | ||
| pub use super::testing::try_writeable_to_parts_for_test; | ||
| pub use super::testing::writeable_to_parts_for_test; | ||
| pub use alloc::string::String; | ||
| } | ||
@@ -165,6 +193,8 @@ | ||
| /// [`Part`]s are used as annotations for formatted strings. For example, a string like | ||
| /// `Alice, Bob` could assign a `NAME` part to the substrings `Alice` and `Bob`, and a | ||
| /// `PUNCTUATION` part to `, `. This allows for example to apply styling only to names. | ||
| /// [`Part`]s are used as annotations for formatted strings. | ||
| /// | ||
| /// For example, a string like `Alice, Bob` could assign a `NAME` part to the | ||
| /// substrings `Alice` and `Bob`, and a `PUNCTUATION` part to `, `. This allows | ||
| /// for example to apply styling only to names. | ||
| /// | ||
| /// `Part` contains two fields, whose usage is left up to the producer of the [`Writeable`]. | ||
@@ -287,47 +317,2 @@ /// Conventionally, the `category` field will identify the formatting logic that produces | ||
| } | ||
| /// Compares the contents of this `Writeable` to the given bytes | ||
| /// without allocating a String to hold the `Writeable` contents. | ||
| /// | ||
| /// This returns a lexicographical comparison, the same as if the Writeable | ||
| /// were first converted to a String and then compared with `Ord`. For a | ||
| /// locale-sensitive string ordering, use an ICU4X Collator. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use core::cmp::Ordering; | ||
| /// use core::fmt; | ||
| /// use writeable::Writeable; | ||
| /// | ||
| /// struct WelcomeMessage<'s> { | ||
| /// pub name: &'s str, | ||
| /// } | ||
| /// | ||
| /// impl<'s> Writeable for WelcomeMessage<'s> { | ||
| /// // see impl in Writeable docs | ||
| /// # fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| /// # sink.write_str("Hello, ")?; | ||
| /// # sink.write_str(self.name)?; | ||
| /// # sink.write_char('!')?; | ||
| /// # Ok(()) | ||
| /// # } | ||
| /// } | ||
| /// | ||
| /// let message = WelcomeMessage { name: "Alice" }; | ||
| /// let message_str = message.write_to_string(); | ||
| /// | ||
| /// assert_eq!(Ordering::Equal, message.writeable_cmp_bytes(b"Hello, Alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Greater, message.writeable_cmp_bytes(b"Alice!")); | ||
| /// assert_eq!(Ordering::Greater, (*message_str).cmp("Alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Less, message.writeable_cmp_bytes(b"Hello, Bob!")); | ||
| /// assert_eq!(Ordering::Less, (*message_str).cmp("Hello, Bob!")); | ||
| /// ``` | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| let mut wc = cmp::WriteComparator::new(other); | ||
| let _ = self.write_to(&mut wc); | ||
| wc.finish().reverse() | ||
| } | ||
| } | ||
@@ -340,5 +325,9 @@ | ||
| /// [`print!`](std::print), [`write!`](std::write), etc. | ||
| /// | ||
| /// This macro also adds a concrete `to_string` function. This function will shadow the | ||
| /// standard library `ToString`, using the more efficient writeable-based code path. | ||
| /// To add only `Display`, use the `@display` macro variant. | ||
| #[macro_export] | ||
| macro_rules! impl_display_with_writeable { | ||
| ($type:ty) => { | ||
| (@display, $type:ty) => { | ||
| /// This trait is implemented for compatibility with [`fmt!`](alloc::fmt). | ||
@@ -353,2 +342,15 @@ /// To create a string, [`Writeable::write_to_string`] is usually more efficient. | ||
| }; | ||
| ($type:ty) => { | ||
| $crate::impl_display_with_writeable!(@display, $type); | ||
| impl $type { | ||
| /// Converts the given value to a `String`. | ||
| /// | ||
| /// Under the hood, this uses an efficient [`Writeable`] implementation. | ||
| /// However, in order to avoid allocating a string, it is more efficient | ||
| /// to use [`Writeable`] directly. | ||
| pub fn to_string(&self) -> $crate::_internal::String { | ||
| $crate::Writeable::write_to_string(self).into_owned() | ||
| } | ||
| } | ||
| }; | ||
| } | ||
@@ -371,3 +373,2 @@ | ||
| /// - Validity of size hint | ||
| /// - Reflexivity of `cmp_bytes` and order against largest and smallest strings | ||
| /// | ||
@@ -447,10 +448,2 @@ /// # Examples | ||
| assert_eq!(actual_writeable.to_string(), $expected_str); | ||
| let ordering = $crate::Writeable::writeable_cmp_bytes(actual_writeable, $expected_str.as_bytes()); | ||
| assert_eq!(ordering, core::cmp::Ordering::Equal, $($arg)*); | ||
| let ordering = $crate::Writeable::writeable_cmp_bytes(actual_writeable, "\u{10FFFF}".as_bytes()); | ||
| assert_eq!(ordering, core::cmp::Ordering::Less, $($arg)*); | ||
| if $expected_str != "" { | ||
| let ordering = $crate::Writeable::writeable_cmp_bytes(actual_writeable, "".as_bytes()); | ||
| assert_eq!(ordering, core::cmp::Ordering::Greater, $($arg)*); | ||
| } | ||
| actual_parts // return for assert_writeable_parts_eq | ||
@@ -457,0 +450,0 @@ }}; |
@@ -7,2 +7,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| /// A wrapper around a type implementing [`fmt::Write`] that implements [`PartsWrite`]. | ||
| #[derive(Debug)] | ||
@@ -36,1 +37,81 @@ #[allow(clippy::exhaustive_structs)] // newtype | ||
| } | ||
| /// A [`Writeable`] that writes out the given part. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use writeable::adapters::WithPart; | ||
| /// use writeable::assert_writeable_parts_eq; | ||
| /// use writeable::Part; | ||
| /// | ||
| /// // Simple usage: | ||
| /// | ||
| /// const PART: Part = Part { | ||
| /// category: "foo", | ||
| /// value: "bar", | ||
| /// }; | ||
| /// | ||
| /// assert_writeable_parts_eq!( | ||
| /// WithPart { | ||
| /// writeable: "Hello World", | ||
| /// part: PART | ||
| /// }, | ||
| /// "Hello World", | ||
| /// [(0, 11, PART)], | ||
| /// ); | ||
| /// | ||
| /// // Can be nested: | ||
| /// | ||
| /// const PART2: Part = Part { | ||
| /// category: "foo2", | ||
| /// value: "bar2", | ||
| /// }; | ||
| /// | ||
| /// assert_writeable_parts_eq!( | ||
| /// WithPart { | ||
| /// writeable: WithPart { | ||
| /// writeable: "Hello World", | ||
| /// part: PART | ||
| /// }, | ||
| /// part: PART2 | ||
| /// }, | ||
| /// "Hello World", | ||
| /// [(0, 11, PART), (0, 11, PART2)], | ||
| /// ); | ||
| /// ``` | ||
| #[derive(Debug)] | ||
| #[allow(clippy::exhaustive_structs)] // public adapter | ||
| pub struct WithPart<T: ?Sized> { | ||
| pub part: Part, | ||
| pub writeable: T, | ||
| } | ||
| impl<T: Writeable + ?Sized> Writeable for WithPart<T> { | ||
| #[inline] | ||
| fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| self.writeable.write_to(sink) | ||
| } | ||
| #[inline] | ||
| fn write_to_parts<W: PartsWrite + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| sink.with_part(self.part, |w| self.writeable.write_to_parts(w)) | ||
| } | ||
| #[inline] | ||
| fn writeable_length_hint(&self) -> LengthHint { | ||
| self.writeable.writeable_length_hint() | ||
| } | ||
| #[inline] | ||
| fn write_to_string(&self) -> Cow<str> { | ||
| self.writeable.write_to_string() | ||
| } | ||
| } | ||
| impl<T: Writeable + ?Sized> fmt::Display for WithPart<T> { | ||
| #[inline] | ||
| fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| Writeable::write_to(&self, f) | ||
| } | ||
| } |
+1
-109
@@ -7,3 +7,3 @@ // This file is part of ICU4X. For terms of use, please see the file | ||
| use crate::parts_write_adapter::CoreWriteAsPartsWrite; | ||
| use core::{cmp::Ordering, convert::Infallible}; | ||
| use core::convert::Infallible; | ||
@@ -210,83 +210,2 @@ /// A writeable object that can fail while writing. | ||
| } | ||
| /// Compares the content of this writeable to a byte slice. | ||
| /// | ||
| /// This function compares the "lossy mode" string; for more information, | ||
| /// see [`TryWriteable::try_write_to()`]. | ||
| /// | ||
| /// For more information, see [`Writeable::writeable_cmp_bytes()`]. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use core::cmp::Ordering; | ||
| /// use core::fmt; | ||
| /// use writeable::TryWriteable; | ||
| /// # use writeable::PartsWrite; | ||
| /// # use writeable::LengthHint; | ||
| /// | ||
| /// #[derive(Debug, PartialEq, Eq)] | ||
| /// enum HelloWorldWriteableError { | ||
| /// MissingName | ||
| /// } | ||
| /// | ||
| /// #[derive(Debug, PartialEq, Eq)] | ||
| /// struct HelloWorldWriteable { | ||
| /// pub name: Option<&'static str> | ||
| /// } | ||
| /// | ||
| /// impl TryWriteable for HelloWorldWriteable { | ||
| /// type Error = HelloWorldWriteableError; | ||
| /// // see impl in TryWriteable docs | ||
| /// # fn try_write_to_parts<S: PartsWrite + ?Sized>( | ||
| /// # &self, | ||
| /// # sink: &mut S, | ||
| /// # ) -> Result<Result<(), Self::Error>, fmt::Error> { | ||
| /// # sink.write_str("Hello, ")?; | ||
| /// # // Use `impl TryWriteable for Result` to generate the error part: | ||
| /// # let _ = self.name.ok_or("nobody").try_write_to_parts(sink)?; | ||
| /// # sink.write_char('!')?; | ||
| /// # // Return a doubly-wrapped Result. | ||
| /// # // The outer Result is for fmt::Error, handled by the `?`s above. | ||
| /// # // The inner Result is for our own Self::Error. | ||
| /// # if self.name.is_some() { | ||
| /// # Ok(Ok(())) | ||
| /// # } else { | ||
| /// # Ok(Err(HelloWorldWriteableError::MissingName)) | ||
| /// # } | ||
| /// # } | ||
| /// } | ||
| /// | ||
| /// // Success case: | ||
| /// let writeable = HelloWorldWriteable { name: Some("Alice") }; | ||
| /// let writeable_str = writeable.try_write_to_string().expect("name is Some"); | ||
| /// | ||
| /// assert_eq!(Ordering::Equal, writeable.writeable_cmp_bytes(b"Hello, Alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Greater, writeable.writeable_cmp_bytes(b"Alice!")); | ||
| /// assert_eq!(Ordering::Greater, (*writeable_str).cmp("Alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Less, writeable.writeable_cmp_bytes(b"Hello, Bob!")); | ||
| /// assert_eq!(Ordering::Less, (*writeable_str).cmp("Hello, Bob!")); | ||
| /// | ||
| /// // Failure case: | ||
| /// let writeable = HelloWorldWriteable { name: None }; | ||
| /// let mut writeable_str = String::new(); | ||
| /// let _ = writeable.try_write_to(&mut writeable_str).expect("write to String is infallible"); | ||
| /// | ||
| /// assert_eq!(Ordering::Equal, writeable.writeable_cmp_bytes(b"Hello, nobody!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Greater, writeable.writeable_cmp_bytes(b"Hello, alice!")); | ||
| /// assert_eq!(Ordering::Greater, (*writeable_str).cmp("Hello, alice!")); | ||
| /// | ||
| /// assert_eq!(Ordering::Less, writeable.writeable_cmp_bytes(b"Hello, zero!")); | ||
| /// assert_eq!(Ordering::Less, (*writeable_str).cmp("Hello, zero!")); | ||
| /// ``` | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> Ordering { | ||
| let mut wc = cmp::WriteComparator::new(other); | ||
| let _ = self | ||
| .try_write_to(&mut wc) | ||
| .unwrap_or_else(|fmt::Error| Ok(())); | ||
| wc.finish().reverse() | ||
| } | ||
| } | ||
@@ -340,10 +259,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> Ordering { | ||
| match self { | ||
| Ok(t) => t.writeable_cmp_bytes(other), | ||
| Err(e) => e.writeable_cmp_bytes(other), | ||
| } | ||
| } | ||
| } | ||
@@ -392,7 +303,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| self.0.writeable_cmp_bytes(other) | ||
| } | ||
| } | ||
@@ -448,7 +354,2 @@ | ||
| } | ||
| #[inline] | ||
| fn writeable_cmp_bytes(&self, other: &[u8]) -> core::cmp::Ordering { | ||
| self.0.writeable_cmp_bytes(other) | ||
| } | ||
| } | ||
@@ -472,3 +373,2 @@ | ||
| /// - Validity of size hint | ||
| /// - Reflexivity of `cmp_bytes` and order against largest and smallest strings | ||
| /// | ||
@@ -519,10 +419,2 @@ /// For a usage example, see [`TryWriteable`]. | ||
| } | ||
| let ordering = actual_writeable.writeable_cmp_bytes($expected_str.as_bytes()); | ||
| assert_eq!(ordering, core::cmp::Ordering::Equal, $($arg)*); | ||
| let ordering = actual_writeable.writeable_cmp_bytes("\u{10FFFF}".as_bytes()); | ||
| assert_eq!(ordering, core::cmp::Ordering::Less, $($arg)*); | ||
| if $expected_str != "" { | ||
| let ordering = actual_writeable.writeable_cmp_bytes("".as_bytes()); | ||
| assert_eq!(ordering, core::cmp::Ordering::Greater, $($arg)*); | ||
| } | ||
| actual_parts // return for assert_try_writeable_parts_eq | ||
@@ -529,0 +421,0 @@ }}; |
Sorry, the diff of this file is not supported yet