= i18n_pattern Rizzen Yazston

== Pattern parser and formatter

The parser handles the parsing of string tokens into an Abstract Syntax Tree (AST), checking the grammar of patterns is valid. The parser only does the syntactic analysis of the supplied Token vector.

The formatter takes the AST that was generated by the parser and constructs a string template for values to be substituted into. The formatter also does the semantic analysis of the grammar. Once a string template has been constructed, it can be used multiple times by simply supplying new placeholder values when executing the format() method. Depending on the placeholder type of the pattern, a suitable selection of the available data types can be used, these include the basic String, integers, unsigned integers and floats. In addition to these special ICU4X types are supported such as FixedDecimal, Date, Time and DateTime structs.

See pattern strings.asciidoc in docs of pattern crate for the pattern formatting specification.

== Acknowledgement

Stefano Angeleri for advice on various design aspects of implementing the components of the internationalisation project, and also providing the Italian translation of error message strings.

== Cargo.toml

``` [dependencies] iculocid = "1.1.0" i18nicu-rizzen-yazston = "0.6.1" i18nutility-rizzen-yazston = "0.6.1" i18nlexer-rizzen-yazston = "0.6.1" # Needed for Token, TokenType tree-rizzen-yazston = "0.4.0" icu_provider = "1.2.0"

These are required for the DataProvider.

icuproperties = "1.2.0" icusegmenter = "1.2.0" icuplurals = "1.2.0" icudecimal = "1.2.0" icucalendar = "1.2.0" icudatetime = "1.2.0"

This is required for the DataProvider.

[dependencies.fixed_decimal] version = "0.5.3"

Needed for floating point support.

features = [ "ryu" ] ```

== Examples

``` use i18nicu::IcuDataProvider; use i18nlexer::{Token, TokenType, tokenise}; use i18npattern::{ parse, NodeType, Formatter, FormatterError, PlaceholderValue, CommandRegistry, englishaoran }; use icutestdata::buffer; use icuprovider::serde::AsDeserializingBufferProvider; use icu_locid::Locale; use std::collections::HashMap; use std::rc::Rc; use std::error::Error;

fn patternplural() -> Result<(), Box> { let bufferprovider = buffer(); let dataprovider = bufferprovider.asdeserializing(); let icudataprovider = Rc::new( IcuDataProvider::trynew( &dataprovider )? ); let tokens = tokenise( "There {dogsnumber plural one#onedog other#dogs} in the park.#{dogs are # dogs}{onedog is 1 dog}", &vec![ '{', '}', '`', '#' ], &icudataprovider, ); let tree = parse( tokens.0 )?; let locale: Rc = Rc::new( "en-ZA".parse()? ); let languagetag = Rc::new( locale.tostring() ); let mut formatter = Formatter::trynew( &icudataprovider, &languagetag, &locale, &tree, &commandregistry )?; let mut values = HashMap::::new(); values.insert( "dogsnumber".tostring(), PlaceholderValue::Unsigned( 3 ) ); let result = formatter.format( &values )?; asserteq!( result.as_str(), "There are 3 dogs in the park.", "Strings must be the same." ); Ok( () ) }

fn commanddelayed() -> Result<(), Box> { let bufferprovider = buffer(); let dataprovider = bufferprovider.asdeserializing(); let icudataprovider = Rc::new( IcuDataProvider::trynew( &dataprovider )? ); let tokens = tokenise( "At night {#englishaoran# hunter} {hunter} stalked {#englishaoran # prey} {prey}.", &vec![ '{', '}', '`', '#' ], &icudataprovider, ); let tree = parse( tokens.0 )?; let locale: Rc = Rc::new( "en-ZA".parse()? ); let languagetag = Rc::new( locale.tostring() ); let commandregistry = Rc::new( CommandRegistry::new() ); commandregistry.insert( "englishaoran", englishaoran )?; let mut formatter = Formatter::trynew( &icudataprovider, &languagetag, &locale, &tree, &commandregistry )?; let mut values = HashMap::::new(); values.insert( "hunter".tostring(), PlaceholderValue::String( "owl".tostring() ) ); values.insert( "prey".tostring(), PlaceholderValue::String( "mouse".tostring() ) ); let result = formatter.format( &values )?; asserteq!( result.asstr(), "At night an owl stalked a mouse.", "Strings must be the same." ); Ok( () ) } ```