+132
| // 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::LengthHint; | ||
| impl std::ops::Add<LengthHint> for LengthHint { | ||
| type Output = Self; | ||
| fn add(self, other: LengthHint) -> Self { | ||
| match self { | ||
| LengthHint::Undefined => LengthHint::Undefined, | ||
| LengthHint::Exact(len1) => match other { | ||
| LengthHint::Undefined => LengthHint::Undefined, | ||
| LengthHint::Exact(len2) => LengthHint::Exact(len1 + len2), | ||
| }, | ||
| } | ||
| } | ||
| } | ||
| impl std::ops::AddAssign<LengthHint> for LengthHint { | ||
| fn add_assign(&mut self, other: Self) { | ||
| *self = *self + other; | ||
| } | ||
| } | ||
| impl std::iter::Sum<LengthHint> for LengthHint { | ||
| fn sum<I>(iter: I) -> Self | ||
| where | ||
| I: Iterator<Item = LengthHint>, | ||
| { | ||
| iter.fold(LengthHint::Exact(0), std::ops::Add::add) | ||
| } | ||
| } | ||
| impl std::ops::Add<usize> for LengthHint { | ||
| type Output = Self; | ||
| fn add(self, other: usize) -> Self { | ||
| match self { | ||
| LengthHint::Undefined => LengthHint::Undefined, | ||
| LengthHint::Exact(len) => LengthHint::Exact(len + other), | ||
| } | ||
| } | ||
| } | ||
| impl std::ops::AddAssign<usize> for LengthHint { | ||
| fn add_assign(&mut self, other: usize) { | ||
| *self = *self + other; | ||
| } | ||
| } | ||
| impl std::iter::Sum<usize> for LengthHint { | ||
| fn sum<I>(iter: I) -> Self | ||
| where | ||
| I: Iterator<Item = usize>, | ||
| { | ||
| LengthHint::Exact(iter.sum::<usize>()) | ||
| } | ||
| } | ||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::*; | ||
| #[test] | ||
| fn test_add() { | ||
| assert_eq!(LengthHint::Exact(5), LengthHint::Exact(3) + 2); | ||
| assert_eq!( | ||
| LengthHint::Exact(5), | ||
| LengthHint::Exact(3) + LengthHint::Exact(2) | ||
| ); | ||
| assert_eq!( | ||
| LengthHint::Undefined, | ||
| LengthHint::Exact(3) + LengthHint::Undefined | ||
| ); | ||
| assert_eq!(LengthHint::Undefined, LengthHint::Undefined + 2); | ||
| assert_eq!( | ||
| LengthHint::Undefined, | ||
| LengthHint::Undefined + LengthHint::Exact(2) | ||
| ); | ||
| assert_eq!( | ||
| LengthHint::Undefined, | ||
| LengthHint::Undefined + LengthHint::Undefined | ||
| ); | ||
| let mut len = LengthHint::Exact(5); | ||
| len += LengthHint::Exact(3); | ||
| assert_eq!(LengthHint::Exact(8), len); | ||
| len += 2; | ||
| assert_eq!(LengthHint::Exact(10), len); | ||
| len += LengthHint::Undefined; | ||
| assert_eq!(LengthHint::Undefined, len); | ||
| len += LengthHint::Exact(3); | ||
| assert_eq!(LengthHint::Undefined, len); | ||
| len += 2; | ||
| assert_eq!(LengthHint::Undefined, len); | ||
| len += LengthHint::Undefined; | ||
| assert_eq!(LengthHint::Undefined, len); | ||
| } | ||
| #[test] | ||
| fn test_sum() { | ||
| let lens = vec![ | ||
| LengthHint::Exact(4), | ||
| LengthHint::Exact(1), | ||
| LengthHint::Exact(1), | ||
| ]; | ||
| assert_eq!( | ||
| LengthHint::Exact(6), | ||
| lens.iter().copied().sum::<LengthHint>() | ||
| ); | ||
| let lens = vec![ | ||
| LengthHint::Exact(4), | ||
| LengthHint::Undefined, | ||
| LengthHint::Exact(1), | ||
| ]; | ||
| assert_eq!( | ||
| LengthHint::Undefined, | ||
| lens.iter().copied().sum::<LengthHint>() | ||
| ); | ||
| let lens = vec![4, 1, 1]; | ||
| assert_eq!( | ||
| LengthHint::Exact(6), | ||
| lens.iter().copied().sum::<LengthHint>() | ||
| ); | ||
| } | ||
| } |
| // 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 std::fmt; | ||
| use writeable::assert_writeable_eq; | ||
| use writeable::LengthHint; | ||
| use writeable::Writeable; | ||
| /// A sample type implementing Writeable | ||
| struct WriteableMessage<'s> { | ||
| message: &'s str, | ||
| } | ||
| impl Writeable for WriteableMessage<'_> { | ||
| fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| sink.write_str(self.message) | ||
| } | ||
| fn write_len(&self) -> LengthHint { | ||
| LengthHint::Exact(self.message.len()) | ||
| } | ||
| } | ||
| #[test] | ||
| fn test_basic() { | ||
| let input_string = "hello world"; | ||
| let message = WriteableMessage { | ||
| message: input_string, | ||
| }; | ||
| assert_writeable_eq!(input_string, &message); | ||
| } |
| { | ||
| "git": { | ||
| "sha1": "8c1c3c5a0011d8e8abff68f28220d51709109f30" | ||
| "sha1": "377ba0e6c90280d1dfa6973fce643c439b021c3b" | ||
| } | ||
| } |
+42
-3
@@ -0,3 +1,8 @@ | ||
| // 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 criterion::{black_box, criterion_group, criterion_main, Criterion}; | ||
| use std::fmt; | ||
| use writeable::LengthHint; | ||
| use writeable::Writeable; | ||
@@ -11,8 +16,8 @@ | ||
| impl Writeable for WriteableMessage<'_> { | ||
| fn write_to(&self, sink: &mut dyn fmt::Write) -> fmt::Result { | ||
| fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| sink.write_str(self.message) | ||
| } | ||
| fn write_len(&self) -> usize { | ||
| self.message.len() | ||
| fn write_len(&self) -> LengthHint { | ||
| LengthHint::Exact(self.message.len()) | ||
| } | ||
@@ -59,2 +64,3 @@ } | ||
| writeable_benches(c); | ||
| writeable_dyn_benches(c); | ||
| display_benches(c); | ||
@@ -93,2 +99,35 @@ } | ||
| #[cfg(feature = "bench")] | ||
| fn writeable_dyn_benches(c: &mut Criterion) { | ||
| // Same as writeable_to_string, but casts to a dyn fmt::Write | ||
| fn writeable_dyn_to_string(w: &impl Writeable) -> String { | ||
| let mut output = String::with_capacity(w.write_len().capacity()); | ||
| w.write_to(&mut output as &mut dyn fmt::Write) | ||
| .expect("impl Write for String is infallible"); | ||
| output | ||
| } | ||
| c.bench_function("writeable_dyn/to_string/short", |b| { | ||
| b.iter(|| { | ||
| writeable_dyn_to_string(&WriteableMessage { | ||
| message: black_box(SHORT_STR), | ||
| }) | ||
| }); | ||
| }); | ||
| c.bench_function("writeable_dyn/to_string/medium", |b| { | ||
| b.iter(|| { | ||
| writeable_dyn_to_string(&WriteableMessage { | ||
| message: black_box(MEDIUM_STR), | ||
| }) | ||
| }); | ||
| }); | ||
| c.bench_function("writeable_dyn/to_string/long", |b| { | ||
| b.iter(|| { | ||
| writeable_dyn_to_string(&WriteableMessage { | ||
| message: black_box(LONG_STR), | ||
| }) | ||
| }); | ||
| }); | ||
| } | ||
| #[cfg(feature = "bench")] | ||
| fn display_benches(c: &mut Criterion) { | ||
@@ -95,0 +134,0 @@ c.bench_function("display/to_string/short", |b| { |
+110
-92
@@ -28,5 +28,5 @@ # This file is automatically @generated by Cargo. | ||
| name = "bstr" | ||
| version = "0.2.14" | ||
| version = "0.2.15" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" | ||
| checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" | ||
| dependencies = [ | ||
@@ -41,17 +41,17 @@ "lazy_static", | ||
| name = "bumpalo" | ||
| version = "3.4.0" | ||
| version = "3.6.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" | ||
| checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" | ||
| [[package]] | ||
| name = "byteorder" | ||
| version = "1.3.4" | ||
| version = "1.4.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" | ||
| checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" | ||
| [[package]] | ||
| name = "cast" | ||
| version = "0.2.3" | ||
| version = "0.2.5" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0" | ||
| checksum = "cc38c385bfd7e444464011bb24820f40dd1c76bcdfa1b78611cb7c2e5cafab75" | ||
| dependencies = [ | ||
@@ -63,8 +63,2 @@ "rustc_version", | ||
| name = "cfg-if" | ||
| version = "0.1.10" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | ||
| [[package]] | ||
| name = "cfg-if" | ||
| version = "1.0.0" | ||
@@ -86,12 +80,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| [[package]] | ||
| name = "const_fn" | ||
| version = "0.4.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab" | ||
| [[package]] | ||
| name = "criterion" | ||
| version = "0.3.3" | ||
| version = "0.3.4" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "70daa7ceec6cf143990669a04c7df13391d55fb27bd4079d252fca774ba244d8" | ||
| checksum = "ab327ed7354547cc2ef43cbe20ef68b988e70b4b593cbd66a2a61733123a3d23" | ||
| dependencies = [ | ||
@@ -103,3 +91,3 @@ "atty", | ||
| "csv", | ||
| "itertools", | ||
| "itertools 0.10.0", | ||
| "lazy_static", | ||
@@ -126,3 +114,3 @@ "num-traits", | ||
| "cast", | ||
| "itertools", | ||
| "itertools 0.9.0", | ||
| ] | ||
@@ -132,7 +120,7 @@ | ||
| name = "crossbeam-channel" | ||
| version = "0.5.0" | ||
| version = "0.5.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775" | ||
| checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" | ||
| dependencies = [ | ||
| "cfg-if 1.0.0", | ||
| "cfg-if", | ||
| "crossbeam-utils", | ||
@@ -147,3 +135,3 @@ ] | ||
| dependencies = [ | ||
| "cfg-if 1.0.0", | ||
| "cfg-if", | ||
| "crossbeam-epoch", | ||
@@ -155,8 +143,7 @@ "crossbeam-utils", | ||
| name = "crossbeam-epoch" | ||
| version = "0.9.0" | ||
| version = "0.9.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f" | ||
| checksum = "2584f639eb95fea8c798496315b297cf81b9b58b6d30ab066a75455333cf4b12" | ||
| dependencies = [ | ||
| "cfg-if 1.0.0", | ||
| "const_fn", | ||
| "cfg-if", | ||
| "crossbeam-utils", | ||
@@ -170,9 +157,8 @@ "lazy_static", | ||
| name = "crossbeam-utils" | ||
| version = "0.8.0" | ||
| version = "0.8.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5" | ||
| checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" | ||
| dependencies = [ | ||
| "autocfg", | ||
| "cfg-if 1.0.0", | ||
| "const_fn", | ||
| "cfg-if", | ||
| "lazy_static", | ||
@@ -183,5 +169,5 @@ ] | ||
| name = "csv" | ||
| version = "1.1.4" | ||
| version = "1.1.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "fc4666154fd004af3fd6f1da2e81a96fd5a81927fe8ddb6ecc79e2aa6e138b54" | ||
| checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" | ||
| dependencies = [ | ||
@@ -212,11 +198,11 @@ "bstr", | ||
| name = "half" | ||
| version = "1.6.0" | ||
| version = "1.7.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "d36fab90f82edc3c747f9d438e06cf0a491055896f2a279638bb5beed6c40177" | ||
| checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" | ||
| [[package]] | ||
| name = "hermit-abi" | ||
| version = "0.1.17" | ||
| version = "0.1.18" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" | ||
| checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" | ||
| dependencies = [ | ||
@@ -227,2 +213,8 @@ "libc", | ||
| [[package]] | ||
| name = "icu_benchmark_macros" | ||
| version = "0.2.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "53af96177ef51245c6a7a4eb7be5f30631b5c536779e5eec63ce6e41cf0edcf6" | ||
| [[package]] | ||
| name = "itertools" | ||
@@ -237,12 +229,21 @@ version = "0.9.0" | ||
| [[package]] | ||
| name = "itertools" | ||
| version = "0.10.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319" | ||
| dependencies = [ | ||
| "either", | ||
| ] | ||
| [[package]] | ||
| name = "itoa" | ||
| version = "0.4.6" | ||
| version = "0.4.7" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" | ||
| checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" | ||
| [[package]] | ||
| name = "js-sys" | ||
| version = "0.3.45" | ||
| version = "0.3.50" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8" | ||
| checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" | ||
| dependencies = [ | ||
@@ -260,13 +261,13 @@ "wasm-bindgen", | ||
| name = "libc" | ||
| version = "0.2.80" | ||
| version = "0.2.94" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" | ||
| checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e" | ||
| [[package]] | ||
| name = "log" | ||
| version = "0.4.11" | ||
| version = "0.4.14" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" | ||
| checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" | ||
| dependencies = [ | ||
| "cfg-if 0.1.10", | ||
| "cfg-if", | ||
| ] | ||
@@ -282,5 +283,5 @@ | ||
| name = "memoffset" | ||
| version = "0.5.6" | ||
| version = "0.6.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" | ||
| checksum = "f83fb6581e8ed1f85fd45c116db8405483899489e38406156c25eb743554361d" | ||
| dependencies = [ | ||
@@ -311,14 +312,15 @@ "autocfg", | ||
| name = "oorandom" | ||
| version = "11.1.2" | ||
| version = "11.1.3" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "a170cebd8021a008ea92e4db85a72f80b35df514ec664b296fdcbb654eac0b2c" | ||
| checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" | ||
| [[package]] | ||
| name = "plotters" | ||
| version = "0.2.15" | ||
| version = "0.3.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "0d1685fbe7beba33de0330629da9d955ac75bd54f33d7b79f9a895590124f6bb" | ||
| checksum = "45ca0ae5f169d0917a7c7f5a9c1a3d3d9598f18f529dd2b8373ed988efea307a" | ||
| dependencies = [ | ||
| "js-sys", | ||
| "num-traits", | ||
| "plotters-backend", | ||
| "plotters-svg", | ||
| "wasm-bindgen", | ||
@@ -329,6 +331,21 @@ "web-sys", | ||
| [[package]] | ||
| name = "plotters-backend" | ||
| version = "0.3.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b07fffcddc1cb3a1de753caa4e4df03b79922ba43cf882acc1bdd7e8df9f4590" | ||
| [[package]] | ||
| name = "plotters-svg" | ||
| version = "0.3.0" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b38a02e23bd9604b842a812063aec4ef702b57989c37b655254bb61c471ad211" | ||
| dependencies = [ | ||
| "plotters-backend", | ||
| ] | ||
| [[package]] | ||
| name = "proc-macro2" | ||
| version = "1.0.24" | ||
| version = "1.0.26" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" | ||
| checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" | ||
| dependencies = [ | ||
@@ -340,5 +357,5 @@ "unicode-xid", | ||
| name = "quote" | ||
| version = "1.0.7" | ||
| version = "1.0.9" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" | ||
| checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" | ||
| dependencies = [ | ||
@@ -375,5 +392,5 @@ "proc-macro2", | ||
| name = "regex" | ||
| version = "1.4.2" | ||
| version = "1.4.6" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" | ||
| checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" | ||
| dependencies = [ | ||
@@ -394,5 +411,5 @@ "regex-syntax", | ||
| name = "regex-syntax" | ||
| version = "0.6.21" | ||
| version = "0.6.23" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" | ||
| checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548" | ||
@@ -446,5 +463,5 @@ [[package]] | ||
| name = "serde" | ||
| version = "1.0.117" | ||
| version = "1.0.125" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" | ||
| checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" | ||
@@ -463,5 +480,5 @@ [[package]] | ||
| name = "serde_derive" | ||
| version = "1.0.117" | ||
| version = "1.0.125" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" | ||
| checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" | ||
| dependencies = [ | ||
@@ -475,5 +492,5 @@ "proc-macro2", | ||
| name = "serde_json" | ||
| version = "1.0.59" | ||
| version = "1.0.64" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95" | ||
| checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" | ||
| dependencies = [ | ||
@@ -487,5 +504,5 @@ "itoa", | ||
| name = "syn" | ||
| version = "1.0.48" | ||
| version = "1.0.71" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac" | ||
| checksum = "ad184cc9470f9117b2ac6817bfe297307418819ba40552f9b3846f05c33d5373" | ||
| dependencies = [ | ||
@@ -508,5 +525,5 @@ "proc-macro2", | ||
| name = "tinytemplate" | ||
| version = "1.1.0" | ||
| version = "1.2.1" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6d3dc76004a03cec1c5932bca4cdc2e39aaa798e3f82363dd94f9adf6098c12f" | ||
| checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" | ||
| dependencies = [ | ||
@@ -531,5 +548,5 @@ "serde", | ||
| name = "walkdir" | ||
| version = "2.3.1" | ||
| version = "2.3.2" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" | ||
| checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" | ||
| dependencies = [ | ||
@@ -543,7 +560,7 @@ "same-file", | ||
| name = "wasm-bindgen" | ||
| version = "0.2.68" | ||
| version = "0.2.73" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42" | ||
| checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" | ||
| dependencies = [ | ||
| "cfg-if 0.1.10", | ||
| "cfg-if", | ||
| "wasm-bindgen-macro", | ||
@@ -554,5 +571,5 @@ ] | ||
| name = "wasm-bindgen-backend" | ||
| version = "0.2.68" | ||
| version = "0.2.73" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68" | ||
| checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" | ||
| dependencies = [ | ||
@@ -570,5 +587,5 @@ "bumpalo", | ||
| name = "wasm-bindgen-macro" | ||
| version = "0.2.68" | ||
| version = "0.2.73" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038" | ||
| checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" | ||
| dependencies = [ | ||
@@ -581,5 +598,5 @@ "quote", | ||
| name = "wasm-bindgen-macro-support" | ||
| version = "0.2.68" | ||
| version = "0.2.73" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe" | ||
| checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" | ||
| dependencies = [ | ||
@@ -595,11 +612,11 @@ "proc-macro2", | ||
| name = "wasm-bindgen-shared" | ||
| version = "0.2.68" | ||
| version = "0.2.73" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307" | ||
| checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" | ||
| [[package]] | ||
| name = "web-sys" | ||
| version = "0.3.45" | ||
| version = "0.3.50" | ||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d" | ||
| checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" | ||
| dependencies = [ | ||
@@ -643,5 +660,6 @@ "js-sys", | ||
| name = "writeable" | ||
| version = "0.1.0" | ||
| version = "0.2.0" | ||
| dependencies = [ | ||
| "criterion", | ||
| "icu_benchmark_macros", | ||
| ] |
+6
-2
@@ -16,5 +16,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| name = "writeable" | ||
| version = "0.1.0" | ||
| version = "0.2.0" | ||
| authors = ["The ICU4X Project Developers"] | ||
| include = ["src/**/*", "examples/**/*", "benches/**/*", "Cargo.toml", "README.md"] | ||
| include = ["src/**/*", "examples/**/*", "benches/**/*", "tests/**/*", "Cargo.toml", "README.md"] | ||
| description = "A more efficient alternative to fmt::Display" | ||
@@ -26,2 +26,3 @@ readme = "README.md" | ||
| [lib] | ||
| path = "src/lib.rs" | ||
| bench = false | ||
@@ -35,4 +36,7 @@ | ||
| [dev-dependencies.icu_benchmark_macros] | ||
| version = "0.2" | ||
| [features] | ||
| bench = [] | ||
| default = [] |
| // 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/master/LICENSE ). | ||
| // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
| // This example illustrates a very simple type implementing Writeable. | ||
| icu_benchmark_macros::static_setup!(); | ||
| use std::fmt; | ||
| use writeable::LengthHint; | ||
| use writeable::Writeable; | ||
@@ -15,8 +17,8 @@ | ||
| impl Writeable for WriteableMessage<'_> { | ||
| fn write_to(&self, sink: &mut dyn fmt::Write) -> fmt::Result { | ||
| fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| sink.write_str(self.message) | ||
| } | ||
| fn write_len(&self) -> usize { | ||
| self.message.len() | ||
| fn write_len(&self) -> LengthHint { | ||
| LengthHint::Exact(self.message.len()) | ||
| } | ||
@@ -26,2 +28,4 @@ } | ||
| fn main() { | ||
| icu_benchmark_macros::main_setup!(); | ||
| let writeable = WriteableMessage { | ||
@@ -28,0 +32,0 @@ message: "hello world", |
+116
-20
| // 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/master/LICENSE ). | ||
| // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). | ||
| //! `writeable` is a utility crate of the [`ICU4X`] project. | ||
@@ -15,25 +16,102 @@ //! | ||
| //! | ||
| //! Types implementing Writeable automatically implement ToString. Because of this, you cannot | ||
| //! implement both Writeable and std::fmt::Display on the same type. | ||
| //! Types implementing Writeable have a defaulted writeable_to_string function. | ||
| //! If desired, types implementing Writeable can manually implement ToString | ||
| //! to wrap writeable_to_string. | ||
| //! | ||
| //! [`Writeable`]: ./trait.Writeable.html | ||
| //! # Examples | ||
| //! | ||
| //! ``` | ||
| //! use writeable::Writeable; | ||
| //! use writeable::LengthHint; | ||
| //! use writeable::assert_writeable_eq; | ||
| //! use std::fmt; | ||
| //! | ||
| //! struct WelcomeMessage<'s>{ | ||
| //! pub name: &'s str, | ||
| //! } | ||
| //! | ||
| //! impl<'s> Writeable for WelcomeMessage<'s> { | ||
| //! 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(()) | ||
| //! } | ||
| //! | ||
| //! fn write_len(&self) -> LengthHint { | ||
| //! // "Hello, " + '!' + length of name | ||
| //! LengthHint::Exact(8 + self.name.len()) | ||
| //! } | ||
| //! } | ||
| //! | ||
| //! let message = WelcomeMessage { name: "Alice" }; | ||
| //! assert_writeable_eq!("Hello, Alice!", &message); | ||
| //! ``` | ||
| //! | ||
| //! [`ICU4X`]: ../icu/index.html | ||
| mod ops; | ||
| use std::fmt; | ||
| /// A hint to help consumers of Writeable pre-allocate bytes before they call write_to. | ||
| /// | ||
| /// LengthHint implements std::ops::Add and similar traits for easy composition. | ||
| /// | ||
| /// See this issue for more info: <https://github.com/unicode-org/icu4x/issues/370>. | ||
| #[derive(Debug, PartialEq, Eq, Copy, Clone)] | ||
| pub enum LengthHint { | ||
| /// Default value: no hint is provided. | ||
| Undefined, | ||
| /// An exact length hint. This value is expected to equal the actual length from write_to. | ||
| Exact(usize), | ||
| } | ||
| impl LengthHint { | ||
| /// Returns a recommendation for the number of bytes to pre-allocate. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use writeable::Writeable; | ||
| /// | ||
| /// fn pre_allocate_string(w: &impl Writeable) -> String { | ||
| /// String::with_capacity(w.write_len().capacity()) | ||
| /// } | ||
| /// ``` | ||
| pub fn capacity(&self) -> usize { | ||
| match self { | ||
| Self::Undefined => 0, | ||
| Self::Exact(len) => *len, | ||
| } | ||
| } | ||
| /// Returns whether the LengthHint indicates that the string is exactly 0 bytes long. | ||
| pub fn is_zero(&self) -> bool { | ||
| match self { | ||
| Self::Undefined => false, | ||
| Self::Exact(len) => *len == 0, | ||
| } | ||
| } | ||
| } | ||
| /// Writeable is an alternative to std::fmt::Display with the addition of a length function. | ||
| pub trait Writeable { | ||
| /// Writes bytes to the given sink. Errors from the sink are bubbled up. | ||
| fn write_to(&self, sink: &mut dyn fmt::Write) -> fmt::Result; | ||
| fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result; | ||
| /// Returns an estimation of the number of bytes that will be written to the sink. The actual | ||
| /// number of bytes may be slightly different than what this function returns. | ||
| /// Returns a hint for the number of bytes that will be written to the sink. | ||
| /// | ||
| /// This function may return an enumeration in the future. See: | ||
| /// https://github.com/unicode-org/icu4x/issues/370 | ||
| fn write_len(&self) -> usize; | ||
| /// Override this method if it can be computed quickly. | ||
| fn write_len(&self) -> LengthHint { | ||
| LengthHint::Undefined | ||
| } | ||
| /// Creates a new String with the data from this Writeable. Like ToString, but faster. | ||
| /// Creates a new String with the data from this Writeable. Like ToString, | ||
| /// but smaller and faster. | ||
| /// | ||
| /// Not intended to be overriden. | ||
| fn writeable_to_string(&self) -> String { | ||
| let mut output = String::with_capacity(self.write_len()); | ||
| let mut output = String::with_capacity(self.write_len().capacity()); | ||
| self.write_to(&mut output) | ||
@@ -51,6 +129,7 @@ .expect("impl Write for String is infallible"); | ||
| /// | ||
| /// # Example | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// use writeable::Writeable; | ||
| /// use writeable::LengthHint; | ||
| /// use writeable::assert_writeable_eq; | ||
@@ -61,7 +140,7 @@ /// use std::fmt; | ||
| /// impl Writeable for Demo { | ||
| /// fn write_to(&self, sink: &mut dyn fmt::Write) -> fmt::Result { | ||
| /// fn write_to<W: fmt::Write + ?Sized>(&self, sink: &mut W) -> fmt::Result { | ||
| /// sink.write_str("foo") | ||
| /// } | ||
| /// fn write_len(&self) -> usize { | ||
| /// 3 | ||
| /// fn write_len(&self) -> LengthHint { | ||
| /// LengthHint::Exact(3) | ||
| /// } | ||
@@ -71,10 +150,27 @@ /// } | ||
| /// assert_writeable_eq!("foo", &Demo); | ||
| /// assert_writeable_eq!("foo", &Demo, "Message: {}", "Hello World"); | ||
| /// ``` | ||
| #[macro_export] | ||
| macro_rules! assert_writeable_eq { | ||
| ($expected_str:expr, $actual_writeable:expr) => { | ||
| let writeable: &dyn Writeable = $actual_writeable; | ||
| assert_eq!($expected_str, writeable.writeable_to_string()); | ||
| assert_eq!($expected_str.len(), writeable.write_len()); | ||
| ($expected_str:expr, $actual_writeable:expr $(,)?) => { | ||
| { | ||
| use $crate::Writeable; | ||
| let writeable = $actual_writeable; | ||
| assert_eq!($expected_str, writeable.writeable_to_string()); | ||
| if let $crate::LengthHint::Exact(len) = writeable.write_len() { | ||
| assert_eq!($expected_str.len(), len); | ||
| } | ||
| } | ||
| }; | ||
| ($expected_str:expr, $actual_writeable:expr, $($arg:tt)+) => { | ||
| { | ||
| use $crate::Writeable; | ||
| let writeable = $actual_writeable; | ||
| assert_eq!($expected_str, writeable.writeable_to_string(), $($arg)+); | ||
| if let $crate::LengthHint::Exact(len) = writeable.write_len() { | ||
| assert_eq!($expected_str.len(), len, $($arg)+); | ||
| } | ||
| } | ||
| }; | ||
| } |
Sorry, the diff of this file is not supported yet