From 763efbb3041d108ca0813485f3ec30bca5d61a2c Mon Sep 17 00:00:00 2001 From: "Shane F. Carr" Date: Wed, 18 Aug 2021 03:01:09 -0500 Subject: [PATCH] Add Writeable impls for u8 and u16 for another small code size improvement --- provider/core/src/resource.rs | 23 +++------ utils/writeable/src/impls.rs | 91 +++++++++++++++++++++++++++++++++++ utils/writeable/src/lib.rs | 1 + 3 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 utils/writeable/src/impls.rs diff --git a/provider/core/src/resource.rs b/provider/core/src/resource.rs index b3a357de323..a425bc8fb09 100644 --- a/provider/core/src/resource.rs +++ b/provider/core/src/resource.rs @@ -16,6 +16,7 @@ use core::fmt; use core::fmt::Write; use icu_locid::LanguageIdentifier; use tinystr::{TinyStr16, TinyStr4}; +use writeable::{LengthHint, Writeable}; /// A top-level collection of related resource keys. #[non_exhaustive] @@ -133,35 +134,25 @@ impl fmt::Debug for ResourceKey { impl fmt::Display for ResourceKey { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeable::Writeable::write_to(self, f) + Writeable::write_to(self, f) } } -impl writeable::Writeable for ResourceKey { +impl Writeable for ResourceKey { fn write_to(&self, sink: &mut W) -> core::fmt::Result { sink.write_str(&self.category.as_str())?; sink.write_char('/')?; sink.write_str(self.sub_category.as_str())?; sink.write_char('@')?; - write!(sink, "{}", self.version)?; + self.version.write_to(sink)?; Ok(()) } - fn write_len(&self) -> writeable::LengthHint { - writeable::LengthHint::Exact(2) + fn write_len(&self) -> LengthHint { + LengthHint::Exact(2) + self.category.as_str().len() + self.sub_category.len() - + if self.version < 10 { - 1 - } else if self.version < 100 { - 2 - } else if self.version < 1000 { - 3 - } else if self.version < 10000 { - 4 - } else { - 5 - } + + self.version.write_len() } } diff --git a/utils/writeable/src/impls.rs b/utils/writeable/src/impls.rs new file mode 100644 index 00000000000..4d4f6d2244f --- /dev/null +++ b/utils/writeable/src/impls.rs @@ -0,0 +1,91 @@ +// 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; +use crate::Writeable; +use core::convert::TryFrom; +use core::fmt; +use core::str; + +impl Writeable for u8 { + fn write_to(&self, sink: &mut W) -> fmt::Result { + let mut buf = [b'0'; 3]; + let mut n = *self; + let mut i = 3usize; + while n != 0 { + i -= 1; + buf[i] = b'0' + (n % 10); + n /= 10; + } + if i == 3 { + debug_assert_eq!(*self, 0); + i = 2; + } + let s = unsafe { str::from_utf8_unchecked(&buf[i..]) }; + sink.write_str(s) + } + + fn write_len(&self) -> LengthHint { + if *self < 10 { + LengthHint::Exact(1) + } else if *self < 100 { + LengthHint::Exact(2) + } else { + LengthHint::Exact(3) + } + } +} + +impl Writeable for u16 { + fn write_to(&self, sink: &mut W) -> fmt::Result { + let mut buf = [b'0'; 5]; + let mut n = *self; + let mut i = 5usize; + while n != 0 { + i -= 1; + buf[i] = b'0' + u8::try_from(n % 10).expect("<10"); + n /= 10; + } + if i == 5 { + debug_assert_eq!(*self, 0); + i = 4; + } + let s = unsafe { str::from_utf8_unchecked(&buf[i..]) }; + sink.write_str(s) + } + + fn write_len(&self) -> LengthHint { + if *self < 10 { + LengthHint::Exact(1) + } else if *self < 100 { + LengthHint::Exact(2) + } else if *self < 1000 { + LengthHint::Exact(3) + } else if *self < 10000 { + LengthHint::Exact(4) + } else { + LengthHint::Exact(5) + } + } +} + +#[test] +fn test_u8() { + use crate::assert_writeable_eq; + assert_writeable_eq!("0", &0u8); + assert_writeable_eq!("1", &1u8); + assert_writeable_eq!("10", &10u8); + assert_writeable_eq!("99", &99u8); + assert_writeable_eq!("255", &255u8); +} + +#[test] +fn test_u16() { + use crate::assert_writeable_eq; + assert_writeable_eq!("0", &0u16); + assert_writeable_eq!("1", &1u16); + assert_writeable_eq!("10", &10u16); + assert_writeable_eq!("99", &99u16); + assert_writeable_eq!("65535", &65535u16); +} diff --git a/utils/writeable/src/lib.rs b/utils/writeable/src/lib.rs index 3bf9712804c..7b8cb88f517 100644 --- a/utils/writeable/src/lib.rs +++ b/utils/writeable/src/lib.rs @@ -53,6 +53,7 @@ extern crate alloc; +mod impls; mod ops; use alloc::string::String;