Skip to content

Commit

Permalink
Merge ffe9b5d into 52d72f5
Browse files Browse the repository at this point in the history
  • Loading branch information
Manishearth committed Aug 14, 2018
2 parents 52d72f5 + ffe9b5d commit 01a2c47
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 6 deletions.
2 changes: 1 addition & 1 deletion intl_pluralrules/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl IntlPluralRules {
/// assert_eq!(pr_naq.select(2), Ok(PluralCategory::TWO));
/// assert_eq!(pr_naq.select(5), Ok(PluralCategory::OTHER));
/// ```
pub fn select<N: ToString>(&self, number: N) -> Result<PluralCategory, &'static str> {
pub fn select<N: operands::IntoPluralOperands>(&self, number: N) -> Result<PluralCategory, &'static str> {
let ops = operands::PluralOperands::from(number);
let pr = self.function;
match ops {
Expand Down
81 changes: 76 additions & 5 deletions intl_pluralrules/src/operands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,23 @@ impl PluralOperands {
/// t: 45,
/// }), PluralOperands::from(123.45))
/// ```
pub fn from<S: ToString>(num: S) -> Result<Self, &'static str> {
let str_num = num.to_string();
pub fn from<S: IntoPluralOperands>(num: S) -> Result<Self, &'static str> {
num.into_plural()
}
}

// once TryFrom stabilizes we can use that instead
pub trait IntoPluralOperands {
fn into_plural(self) -> Result<PluralOperands, &'static str>;
}

let abs_str = if str_num.starts_with("-") {
&str_num[1..]

impl<'a> IntoPluralOperands for &'a str {
fn into_plural(self) -> Result<PluralOperands, &'static str> {
let abs_str = if self.starts_with("-") {
&self[1..]
} else {
&str_num
&self
};

let absolute_value = f64::from_str(&abs_str).map_err(|_| "Incorrect number passed!")?;
Expand Down Expand Up @@ -130,3 +140,64 @@ impl PluralOperands {
})
}
}

macro_rules! impl_integer_type {
($ty:ident) => {
impl IntoPluralOperands for $ty {
fn into_plural(self) -> Result<PluralOperands, &'static str> {
// XXXManishearth converting from u32 or u64 to isize may wrap
Ok(PluralOperands {
n: self as f64,
i: self as isize,
v: 0,
w: 0,
f: 0,
t: 0,
})
}
}
};
($($ty:ident)+) => {
$(impl_integer_type!($ty);)+
};
}

macro_rules! impl_signed_integer_type {
($ty:ident) => {
impl IntoPluralOperands for $ty {
fn into_plural(self) -> Result<PluralOperands, &'static str> {
// XXXManishearth converting from i64 to isize may wrap
let x = (self as isize).checked_abs().ok_or("Number too big")?;
Ok(PluralOperands {
n: x as f64,
i: x as isize,
v: 0,
w: 0,
f: 0,
t: 0,
})
}
}
};
($($ty:ident)+) => {
$(impl_signed_integer_type!($ty);)+
};
}

macro_rules! impl_convert_type {
($ty:ident) => {
impl IntoPluralOperands for $ty {
fn into_plural(self) -> Result<PluralOperands, &'static str> {
<&str>::into_plural(&*self.to_string())
}
}
};
($($ty:ident)+) => {
$(impl_convert_type!($ty);)+
};
}

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);

0 comments on commit 01a2c47

Please sign in to comment.