1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
// 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 ). //! `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`](Pattern::interpolate_to_string) method //! is being used. //! //! ``` //! use icu_pattern::Pattern; //! use std::{ //! convert::TryInto, //! borrow::Cow, //! 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. //! //! [`ICU4X`]: ../icu/index.html //! [`FromStr`]: std::str::FromStr mod interpolator; mod parser; mod pattern; mod replacement; mod token; pub use interpolator::{InterpolatedKind, Interpolator, InterpolatorError}; pub use parser::{Parser, ParserError, ParserOptions}; pub use pattern::{InterpolatedPattern, Pattern, PatternError}; pub use replacement::ReplacementProvider; pub use token::PatternToken;