Skip to content

Commit

Permalink
Implement From float specialization for PluralOperands
Browse files Browse the repository at this point in the history
  • Loading branch information
zbraniecki committed Jan 29, 2020
1 parent fa1888b commit 01dee8d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
25 changes: 23 additions & 2 deletions intl_pluralrules/benches/pluralrules.rs
Expand Up @@ -3,7 +3,7 @@ use criterion::criterion_main;
use criterion::BenchmarkId;
use criterion::Criterion;

use intl_pluralrules::{PluralRuleType, PluralRules};
use intl_pluralrules::{operands::PluralOperands, PluralRuleType, PluralRules};
use unic_langid::{langid, LanguageIdentifier};

fn plural_rules(c: &mut Criterion) {
Expand Down Expand Up @@ -65,5 +65,26 @@ fn plural_rules(c: &mut Criterion) {
});
}

criterion_group!(benches, plural_rules,);
fn float_operands(c: &mut Criterion) {
let samples = &[
0.23_f64,
2.202_f64,
0.015_f64,
91.212_f64,
5.5_f64,
5.05_f64,
212.0212_f64,
5.0_f64,
];

c.bench_function("parse_float_operands", move |b| {
b.iter(|| {
for sample in samples {
let _ = PluralOperands::from(*sample);
}
})
});
}

criterion_group!(benches, plural_rules, float_operands);
criterion_main!(benches);
39 changes: 29 additions & 10 deletions intl_pluralrules/src/operands.rs
Expand Up @@ -37,16 +37,15 @@
//! From &str
//!
//! ```
//! use std::convert::TryFrom;
//! use intl_pluralrules::operands::*;
//! assert_eq!(Ok(PluralOperands {
//! assert_eq!(PluralOperands {
//! n: 123.45_f64,
//! i: 123,
//! v: 2,
//! w: 2,
//! f: 45,
//! t: 45,
//! }), PluralOperands::try_from(123.45))
//! }, PluralOperands::from(123.45))
//! ```
#![cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))]
use std::convert::TryFrom;
Expand Down Expand Up @@ -167,11 +166,32 @@ macro_rules! impl_signed_integer_type {

macro_rules! impl_convert_type {
($ty:ident) => {
impl TryFrom<$ty> for PluralOperands {
type Error = &'static str;
fn try_from(input: $ty) -> Result<Self, Self::Error> {
let as_str: &str = &input.to_string();
PluralOperands::try_from(as_str)
impl From<$ty> for PluralOperands {
fn from(input: $ty) -> Self {
let eps = 1e-4;
let abs = input.abs();
let mut f = abs.fract();
let (len, fraction) = if f == 0.0 {
(0, 0)
} else {
let mut len = 0;
while (f.round() - f).abs() <= eps {
f *= 10.0;
}
while (f.round() - f).abs() > eps {
f *= 10.0;
len += 1;
}
(len, f.round() as usize)
};
PluralOperands {
n: abs as f64,
i: abs as usize,
v: len,
w: len,
f: fraction,
t: fraction,
}
}
}
};
Expand All @@ -182,5 +202,4 @@ macro_rules! impl_convert_type {

impl_integer_type!(u8 u16 u32 u64 usize);
impl_signed_integer_type!(i8 i16 i32 i64 isize);
// XXXManishearth we can likely have dedicated float impls here
impl_convert_type!(f32 f64 String);
impl_convert_type!(f32 f64);
7 changes: 7 additions & 0 deletions intl_pluralrules/tests/operands.rs
Expand Up @@ -75,6 +75,13 @@ fn test_operands_from_float() {
((0.0203000_f64, 0, 4, 4, 203, 203), 0.0203000),
((123.45_f64, 123, 2, 2, 45, 45), 123.45),
((1234.567_f64, 1234, 3, 3, 567, 567), -1234.567),
((2.202_f64, 2, 3, 3, 202, 202), 2.202),
((0.015_f64, 0, 3, 3, 15, 15), 0.015),
((91.212_f64, 91, 3, 3, 212, 212), 91.212),
((5.5_f64, 5, 1, 1, 5, 5), 5.5),
((5.05_f64, 5, 2, 2, 5, 5), 5.05),
((5.0_f64, 5, 0, 0, 0, 0), 5.0),
((212.0212_f64, 212, 4, 4, 212, 212), 212.0212),
];

for test in tests {
Expand Down

0 comments on commit 01dee8d

Please sign in to comment.