6 releases

0.1.5 Sep 22, 2023
0.1.4 Apr 13, 2023
0.1.3 Jan 26, 2023
0.1.2 May 10, 2022
0.1.0 Apr 29, 2021

#340 in Internationalization (i18n)

Download history 1589/week @ 2023-12-31 927/week @ 2024-01-07 2063/week @ 2024-01-14 1281/week @ 2024-01-21 3245/week @ 2024-01-28 1872/week @ 2024-02-04 2533/week @ 2024-02-11 759/week @ 2024-02-18 2074/week @ 2024-02-25 1755/week @ 2024-03-03 2663/week @ 2024-03-10 1415/week @ 2024-03-17 2636/week @ 2024-03-24 1145/week @ 2024-03-31 3265/week @ 2024-04-07 1170/week @ 2024-04-14

8,216 downloads per month

Custom license

95KB
1.5K SLoC

icu_pattern crates.io

icu_pattern is a utility crate of the ICU4X project.

It includes a Pattern struct which wraps a paid of Parser and Interpolator allowing for parsing and interpolation of ICU placeholder patterns, like "{0} days" or "{0}, {1}" with custom elements and string literals.

Placeholders & Elements

The Parser is generic over any Placeholder which implements FromStr allowing the consumer to parse placeholder patterns such as "{0}, {1}", "{date}, {time}" or any other.

The Interpolator can interpolate the Pattern against any iterator over Element.

Examples

In the following example we're going to use a custom Token type, and an Element type which will be either a Token or a string slice.

For the purpose of the example, a higher level interpolate_to_string method is being used.

use icu_pattern::Pattern;
use std::{borrow::Cow, convert::TryInto, fmt::Display};

#[derive(Debug, PartialEq)]
enum ExampleToken {
    Year,
    Month,
    Day,
    Hour,
    Minute,
}

impl Display for ExampleToken {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "[{:?}]", self)
    }
}

#[derive(Debug, PartialEq)]
enum ExampleElement<'s> {
    Token(ExampleToken),
    Literal(Cow<'s, str>),
}

impl Display for ExampleElement<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Token(token) => token.fmt(f),
            Self::Literal(lit) => lit.fmt(f),
        }
    }
}

let pattern: Pattern<usize> =
    "{0}, {1}".try_into().expect("Failed to parse a pattern.");

let replacements = vec![
    vec![
        ExampleElement::Token(ExampleToken::Year),
        ExampleElement::Literal("-".into()),
        ExampleElement::Token(ExampleToken::Month),
        ExampleElement::Literal("-".into()),
        ExampleElement::Token(ExampleToken::Day),
    ],
    vec![
        ExampleElement::Token(ExampleToken::Hour),
        ExampleElement::Literal(":".into()),
        ExampleElement::Token(ExampleToken::Minute),
    ],
];

assert_eq!(
    pattern
        .interpolate_to_string::<ExampleElement, _>(&replacements)
        .expect("Failed to interpolate a pattern."),
    "[Year]-[Month]-[Day], [Hour]:[Minute]"
);

Combinators

In the example above, the replacements will be parsed at compile time and stored on a [Vec], which is a collection type that has an implementation for ReplacementProvider trait.

In real use, the consumer may want to use different models of replacement provider, and different element schemas. Because the replacement is an iterator itself, it allows for other, more specialized parsers, to be used to lazily parse particular patterns that are meant to replace the placeholders. This allows for lazy parsing of those specialized patterns to be triggered only if the placeholder pattern encounters a placeholder key that requires given pattern to be used.

More Information

For more information on development, authorship, contributing etc. please visit ICU4X home page.

Dependencies

~300–750KB
~18K SLoC