Skip to content

Commit

Permalink
Switch from language_tags to icu_locid.
Browse files Browse the repository at this point in the history
waywardmonkeys committed Oct 14, 2023
1 parent 7c89bee commit 6336a10
Showing 4 changed files with 38 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -12,4 +12,4 @@ repository = "https://github.com/endoli/humanize.rs"
edition = "2021"

[dependencies]
language-tags = "0.2.2"
icu_locid = "1"
30 changes: 17 additions & 13 deletions src/boolean.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
//!
//! ## Parsing
//!
//! For all languages, we support parsing `"1"` and `"0"` as `true`
//! For all locales, we support parsing `"1"` and `"0"` as `true`
//! and `false` respectively.
//!
//! In English, these lexical values map to `true`:
@@ -28,25 +28,29 @@
//! * `"off"`
use crate::Parse;
use language_tags::{langtag, LanguageTag};
use icu_locid::{locale, Locale};

fn locale_matches(left: &Locale, right: &Locale) -> bool {
(*left == *right) || (*left == Locale::UND) || (*right == Locale::UND)
}

impl Parse for bool {
fn parse(text: &str, language: &LanguageTag) -> Option<bool> {
let en = langtag!(en);
fn parse(text: &str, locale: &Locale) -> Option<bool> {
let en = locale!("en");
match &*text.to_lowercase() {
"1" => Some(true),
"0" => Some(false),
"ok" | "okay" | "on" | "true" | "yep" | "yes" if language.matches(&en) => Some(true),
"false" | "no" | "nope" | "off" if language.matches(&en) => Some(false),
"ok" | "okay" | "on" | "true" | "yep" | "yes" if locale_matches(locale, &en) => Some(true),
"false" | "no" | "nope" | "off" if locale_matches(locale, &en) => Some(false),
_ => None,
}
}
}

#[cfg(test)]
mod tests {
use crate::{parse, parse_with_language};
use language_tags::langtag;
use crate::{parse, parse_with_locale};
use icu_locid::locale;

#[test]
fn basic() {
@@ -64,10 +68,10 @@ mod tests {
assert_eq!(Some(false), parse::<bool>("nope"));
assert_eq!(Some(false), parse::<bool>("off"));

let badlang = langtag!("no");
assert_eq!(Some(true), parse_with_language::<bool>("1", &badlang));
assert_eq!(Some(false), parse_with_language::<bool>("0", &badlang));
assert_eq!(None, parse_with_language::<bool>("okay", &badlang));
assert_eq!(None, parse_with_language::<bool>("nope", &badlang));
let bad_locale = locale!("no");
assert_eq!(Some(true), parse_with_locale::<bool>("1", &bad_locale));
assert_eq!(Some(false), parse_with_locale::<bool>("0", &bad_locale));
assert_eq!(None, parse_with_locale::<bool>("okay", &bad_locale));
assert_eq!(None, parse_with_locale::<bool>("nope", &bad_locale));
}
}
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@
//! * The ['at' command]'s input parsing.
//!
//! Contributions extending our functionality are welcome, as are
//! contributions that add support for additional languages.
//! contributions that add support for additional languages / locales.
//!
//! # Human-friendly Parsing
//!
@@ -56,4 +56,4 @@
pub mod boolean;
mod parser;

pub use crate::parser::{parse, parse_or, parse_with_language, parse_with_language_or, Parse};
pub use crate::parser::{parse, parse_or, parse_with_locale, parse_with_locale_or, Parse};
31 changes: 18 additions & 13 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -4,38 +4,43 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use language_tags::LanguageTag;
use icu_locid::Locale;

/// Construct `Self` by parsing humanized text.
pub trait Parse: Sized {
/// Perform the conversion.
fn parse(text: &str, language: &LanguageTag) -> Option<Self>;
fn parse(text: &str, locale: &Locale) -> Option<Self>;
}

/// Construct a value by parsing humanized text.
///
/// This uses a wild card for the language, so text in any language
/// This uses a wild card for the locale, so text in any locale
/// supported by the library should work.
pub fn parse<T: Parse>(text: &str) -> Option<T> {
let language = LanguageTag::default();
T::parse(text, &language)
let locale = Locale::default();
T::parse(text, &locale)
}

/// Construct a value by parsing humanized text, with a default
/// Construct a value by parsing humanized `text`, with a `default`
/// value when parsing fails.
///
/// This uses a wild card for the language, so text in any language
/// This uses a wild card for the locale, so text in any locale
/// supported by the library should work.
pub fn parse_or<T: Parse>(text: &str, default: T) -> T {
parse::<T>(text).unwrap_or(default)
}

/// Construct a value by parsing humanized text using the specified language.
pub fn parse_with_language<T: Parse>(text: &str, language: &LanguageTag) -> Option<T> {
T::parse(text, language)
/// Construct a value by parsing humanized `text` using the specified [`locale`].
///
/// [`locale`]: Locale
pub fn parse_with_locale<T: Parse>(text: &str, locale: &Locale) -> Option<T> {
T::parse(text, locale)
}

/// Construct a value by parsing humanized text using the specified language.
pub fn parse_with_language_or<T: Parse>(text: &str, language: &LanguageTag, default: T) -> T {
T::parse(text, language).unwrap_or(default)
/// Construct a value by parsing humanized `text` using the specified [`locale`],
/// with a `default` value when parsing fails.
///
/// [`locale`]: Locale
pub fn parse_with_locale_or<T: Parse>(text: &str, locale: &Locale, default: T) -> T {
T::parse(text, locale).unwrap_or(default)
}

0 comments on commit 6336a10

Please sign in to comment.