icu_pattern/lib.rs
1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5// https://github.com/unicode-org/icu4x/blob/main/documents/process/boilerplate.md#library-annotations
6#![cfg_attr(not(any(test, doc)), no_std)]
7#![cfg_attr(
8 not(test),
9 deny(
10 clippy::indexing_slicing,
11 clippy::unwrap_used,
12 clippy::expect_used,
13 clippy::panic,
14 )
15)]
16// #![warn(missing_docs)]
17
18//! `icu_pattern` is a utility crate of the [`ICU4X`] project.
19//!
20//! It includes a [`Pattern`] type which supports patterns with various storage backends.
21//!
22//! The types are tightly coupled with the [`writeable`] crate.
23//!
24//! # Examples
25//!
26//! Parsing and interpolating with a single-placeholder pattern:
27//!
28//! ```
29//! use icu_pattern::SinglePlaceholderPattern;
30//! use writeable::assert_writeable_eq;
31//!
32//! // Parse a pattern string:
33//! let pattern = SinglePlaceholderPattern::try_from_str(
34//! "Hello, {0}!",
35//! Default::default(),
36//! )
37//! .unwrap();
38//!
39//! // Interpolate into the pattern string:
40//! assert_writeable_eq!(pattern.interpolate(["World"]), "Hello, World!");
41//! ```
42//!
43//! [`ICU4X`]: ../icu/index.html
44//! [`FromStr`]: core::str::FromStr
45
46#[cfg(feature = "alloc")]
47extern crate alloc;
48
49#[cfg(feature = "alloc")]
50mod builder;
51mod common;
52mod double;
53mod error;
54mod frontend;
55mod multi_named;
56#[cfg(feature = "alloc")]
57mod parser;
58mod single;
59
60#[doc(no_inline)]
61pub use PatternError as Error;
62#[cfg(feature = "unstable")]
63pub use common::ExtractionBackend;
64pub use common::PatternBackend;
65pub use common::PatternItem;
66#[cfg(feature = "alloc")]
67pub use common::PatternItemCow;
68pub use common::PlaceholderValueProvider;
69pub use common::TryWrap;
70pub use double::DoublePlaceholder;
71pub use double::DoublePlaceholderKey;
72pub use error::PatternError;
73pub use frontend::Pattern;
74#[cfg(feature = "unstable")]
75pub use frontend::PlaceholderMatches;
76#[cfg(feature = "serde")]
77pub use frontend::serde::*;
78pub use multi_named::MissingNamedPlaceholderError;
79pub use multi_named::MultiNamedPlaceholder;
80pub use multi_named::MultiNamedPlaceholderKey;
81#[cfg(feature = "alloc")]
82pub use parser::ParsedPatternItem;
83#[cfg(feature = "alloc")]
84pub use parser::Parser;
85#[cfg(feature = "alloc")]
86pub use parser::ParserError;
87#[cfg(feature = "alloc")]
88pub use parser::ParserOptions;
89#[cfg(feature = "alloc")]
90pub use parser::QuoteMode;
91pub use single::SinglePlaceholder;
92pub use single::SinglePlaceholderKey;
93
94mod private {
95 pub trait Sealed {}
96}
97
98/// # Examples
99///
100/// ```
101/// use core::str::FromStr;
102/// use icu_pattern::SinglePlaceholderPattern;
103/// use writeable::assert_writeable_eq;
104///
105/// // Create a pattern from the string syntax:
106/// let pattern = SinglePlaceholderPattern::try_from_str(
107/// "Hello, {0}!",
108/// Default::default(),
109/// )
110/// .unwrap();
111///
112/// // Interpolate some values into the pattern:
113/// assert_writeable_eq!(pattern.interpolate(["Alice"]), "Hello, Alice!");
114/// ```
115pub type SinglePlaceholderPattern = Pattern<SinglePlaceholder>;
116
117impl SinglePlaceholderPattern {
118 /// An instance of [`SinglePlaceholderPattern`] that has a single placeholder and adds no
119 /// prefix or suffix.
120 ///
121 /// # Examples
122 ///
123 /// ```
124 /// use icu_pattern::SinglePlaceholderPattern;
125 /// use writeable::assert_writeable_eq;
126 ///
127 /// assert_eq!(
128 /// SinglePlaceholderPattern::PASS_THROUGH,
129 /// &*SinglePlaceholderPattern::try_from_str("{0}", Default::default())
130 /// .unwrap()
131 /// );
132 ///
133 /// assert_writeable_eq!(
134 /// SinglePlaceholderPattern::PASS_THROUGH.interpolate(["hello, world!"]),
135 /// "hello, world!"
136 /// );
137 /// ```
138 pub const PASS_THROUGH: &'static SinglePlaceholderPattern =
139 SinglePlaceholderPattern::from_ref_store_unchecked("\x01");
140}
141
142/// # Examples
143///
144/// ```
145/// use core::str::FromStr;
146/// use icu_pattern::DoublePlaceholderPattern;
147/// use writeable::assert_writeable_eq;
148///
149/// // Create a pattern from the string syntax:
150/// let pattern = DoublePlaceholderPattern::try_from_str(
151/// "Hello, {0} and {1}!",
152/// Default::default(),
153/// )
154/// .unwrap();
155///
156/// // Interpolate some values into the pattern:
157/// assert_writeable_eq!(
158/// pattern.interpolate(["Alice", "Bob"]),
159/// "Hello, Alice and Bob!"
160/// );
161/// ```
162pub type DoublePlaceholderPattern = Pattern<DoublePlaceholder>;
163
164/// # Examples
165///
166/// ```
167/// use core::str::FromStr;
168/// use icu_pattern::MultiNamedPlaceholderPattern;
169/// use std::collections::BTreeMap;
170/// use writeable::assert_try_writeable_eq;
171///
172/// // Create a pattern from the string syntax:
173/// let pattern = MultiNamedPlaceholderPattern::try_from_str(
174/// "Hello, {person0} and {person1}!",
175/// Default::default(),
176/// )
177/// .unwrap();
178///
179/// // Interpolate some values into the pattern:
180/// assert_try_writeable_eq!(
181/// pattern.try_interpolate(
182/// [("person0", "Alice"), ("person1", "Bob")]
183/// .into_iter()
184/// .collect::<BTreeMap<&str, &str>>()
185/// ),
186/// "Hello, Alice and Bob!"
187/// );
188/// ```
189pub type MultiNamedPlaceholderPattern = Pattern<MultiNamedPlaceholder>;
190
191#[test]
192#[cfg(feature = "alloc")]
193fn test_single_placeholder_pattern_impls() {
194 let a = SinglePlaceholderPattern::try_from_str("{0}", Default::default()).unwrap();
195 let b = SinglePlaceholderPattern::try_from_str("{0}", Default::default()).unwrap();
196 assert_eq!(a, b);
197 let c = b.clone();
198 assert_eq!(a, c);
199}