Skip to content

Commit

Permalink
Add Writeable impls for u8 and u16 for another small code size improv…
Browse files Browse the repository at this point in the history
…ement
  • Loading branch information
sffc committed Aug 18, 2021
1 parent fd18830 commit 763efbb
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 16 deletions.
23 changes: 7 additions & 16 deletions provider/core/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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<W: core::fmt::Write + ?Sized>(&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()
}
}

Expand Down
91 changes: 91 additions & 0 deletions utils/writeable/src/impls.rs
Original file line number Diff line number Diff line change
@@ -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<W: fmt::Write + ?Sized>(&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<W: fmt::Write + ?Sized>(&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);
}
1 change: 1 addition & 0 deletions utils/writeable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

extern crate alloc;

mod impls;
mod ops;

use alloc::string::String;
Expand Down

0 comments on commit 763efbb

Please sign in to comment.