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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
//! # `Ast` and `Manifest` implementations
//!
//! This module provides custom [`Ast`](crate::Ast) and [`Manifest`](crate::Manifest)
//! implementations. It also provides documentation and examples for the implementations on
//! standard library types.
//!
//! Jump to:
//! - [`Ast` implementations](#ast-implementations)
//! - [`Ast` examples](#ast-examples)
//! - [`Manifest` implementations](#manifest-implementations)
//!
//! ## [`Ast`](crate::Ast) implementations
//! The following table summarizes the implementations on standard library types.
//!
//! Types | Parse rules | Syntax Error
//! ------|-------------|------
//! `String`, `&'fmt str`, `PathBuf`, `&'fmt Path` | Captures the literal contents of the expression | [`Infallible`][I]
//! `bool` | literal `true` or `false` | [`ParseBoolError`](std::str::ParseBoolError)
//! `u*`, `i*`, and `NonZero<..>` variants | The number, from a decimal | [`ParseIntError`]
//! `f32`, `f64` | The float, using the rules in [`FromStr`][F2] | [`ParseFloatError`](std::num::ParseFloatError)
//! `()` | Only an empty expression | [`NotEmpty`]
//! [`Infallible`][I] | Always fails to parse | `()`
//! [`Option<T>`] where `T: Ast` | `None` if the expression is empty, else `Some(T)` | The error type of `T`
//! [`Box<T>`], [`Arc<T>`][A], [`Rc<T>`][R] where `T: Ast` | Uses parse rules of `T` | The error type of `T`
//! `Result<T, T::Error>` where `T: Ast` | Uses parse rules of `T`, capturing error | [`Infallible`][I]
//!
//! The following additional types are parsed using their [`FromStr`][F] implementations:
//! - [`IpAddr`](std::net::IpAddr), [`Ipv4Addr`](std::net::Ipv4Addr), [`Ipv6Addr`](std::net::Ipv6Addr), [`SocketAddr`](std::net::SocketAddr), [`SocketAddrV4`](std::net::SocketAddrV4), [`SocketAddrV6`](std::net::SocketAddrV6)
//!
//! You can implement [`Ast`](crate::Ast) on your own types which implement [`FromStr`][F] using the [`Ast`](../derive.Ast.html) derive macro.
//!
//! The following table summarizes the implementations on types defined in this module.
//!
//! Types | Parse rules | Syntax Error
//! ------|-------------|-------------
//! [`BoundedInt<N>`] | A decimal in the range `0..N` | [`ParseBoundedIntError`]
//! [`IgnoredAny`] | Accepts any expression without capturing | [`Infallible`][I]
//!
//! ### `Ast` examples
//! Parse a float in many different formats.
//! ```
//! # use mufmt::Ast;
//! assert_eq!(f64::from_expr("4e2"), Ok(4e2));
//! assert_eq!(f64::from_expr("+infinity"), Ok(f64::INFINITY));
//! ```
//! Parse an `Option<T>`.
//! ```
//! # use mufmt::Ast;
//! assert_eq!(Option::<u8>::from_expr(""), Ok(None));
//! assert_eq!(Option::<u8>::from_expr("3"), Ok(Some(3)));
//!
//! // the `Option` has precedence over the internal type
//! assert_eq!(Option::<String>::from_expr(""), Ok(None));
//! assert_eq!(String::from_expr(""), Ok(String::new()));
//! ```
//! Parse a `Result<T, T::Error>`.
//! ```
//! # use mufmt::Ast;
//! // always returns Ok(_) since the err variant is captured
//! assert!(matches!(Result::<u8, <u8 as Ast>::Error>::from_expr(""), Ok(Err(_))));
//! assert!(matches!(Result::<u16, <u16 as Ast>::Error>::from_expr("12"), Ok(Ok(_))));
//! ```
//!
//! ## [`Manifest`](crate::Manifest) implementations.
//!
//! Types | Accepted `Ast` | Displays | Render Error
//! ------|-----|----------|------
//! [`HashMap<K, V>`][H], [`BTreeMap<K, V>`][B] | Any borrowed format of `K` | Value `V` corresponding to the key | [`KeyMissing`] if the key does not exist
//! [`Vec<T>`], [`VecDeque<T>`][V], `&[T]`, `&mut T`, [`[T]`](std::slice), [`[T; N]`](std::array) | `usize` | Value `T` at the index | [`IndexOutOfRange`] if the index is too large
//! [`[T; N]`](std::array) | [`BoundedInt<N>`] | Value `T` at the index | [`Infallible`][I]
//! `Fn(&A) -> Result<T, E>` | `A` | `T` | `E`
//! [`Placeholder<T>`] | Any | Value `T` | [`Infalible`][I]
//!
//! [A]: std::sync::Arc
//! [R]: std::rc::Rc
//! [I]: std::convert::Infallible
//! [F]: std::str::FromStr
//! [F2]: f64#method.from_str
//! [H]: std::collections::HashMap
//! [B]: std::collections::BTreeMap
//! [V]: std::collections::VecDeque
use ;
pub use ;
pub use Placeholder;
/// An index is out of range.
///
/// This is the error type for the [`Manifest`](crate::Manifest) implementation of container types
/// like [`Vec`] or slices and array types.
/// ```
/// use mufmt::{Template, types::IndexOutOfRange};
///
/// let template = Template::<&str, usize>::compile("User {3}").unwrap();
/// let mut mfst = vec!["Jon", "Thomas"];
///
/// // index `3` is out of range
/// assert_eq!(template.render(&mfst), Err(IndexOutOfRange(3)));
/// ```
;
/// A key is missing.
///
/// This is the error type for the [`Manifest`](crate::Manifest) implementation of container types
/// like [`HashMap`](std::collections::HashMap) and [`BTreeMap`](std::collections::HashMap) when
/// the template contains a key which does not exist in the database.
/// ```
/// use std::collections::HashMap;
/// use mufmt::{Template, types::KeyMissing};
///
/// let template = Template::<&str, &str>::compile("Hello {name}!").unwrap();
/// let mut mfst: HashMap<&'static str, &'static str> = HashMap::new();
/// mfst.insert("age", "37");
///
/// // the key `name` is missing
/// assert_eq!(template.render(&mfst), Err(KeyMissing));
/// ```
/// The missing key is not reported since it cannot be moved out of the template. If your key
/// type is `Clone` or `Copy`, you can implement this feature as follows.
/// ```
/// use std::{borrow::Borrow, collections::HashMap, hash::Hash, fmt::Display};
/// use mufmt::{Manifest, Template};
///
/// struct Wrapper<K, V> {
/// inner: HashMap<K, V>
/// }
///
/// #[derive(Debug, PartialEq)]
/// struct KeyMissing<K>(K);
///
/// impl<Q, K, V> Manifest<Q> for Wrapper<K, V>
/// where
/// K: Borrow<Q> + Eq + Hash,
/// Q: Eq + Hash + Clone, // we need `Clone` to move out of the template
/// V: Display,
///{
/// type Error = KeyMissing<Q>;
///
/// fn manifest(&self, ast: &Q) -> Result<impl Display, Self::Error> {
/// self.inner.get(ast).ok_or_else(|| KeyMissing(ast.clone()))
/// }
///}
///
/// let template = Template::<&str, &str>::compile("Hello {name}!").unwrap();
/// let mut mfst: Wrapper<&'static str, &'static str> = Wrapper {
/// inner: HashMap::new(),
/// };
/// mfst.inner.insert("age", "37");
///
/// // the key `name` is missing
/// assert_eq!(template.render(&mfst), Err(KeyMissing("name")));
/// ```
;
/// An expression was expected to be empty.
///
/// This is the error type for the [`Ast`](crate::Ast) implementation of the unit type
/// `()` which is returned when an expression contains contents.
/// ```
/// use mufmt::{Template, SyntaxErrorKind, types::NotEmpty};
///
/// assert!(Template::<&str, ()>::compile("User {}").is_ok());
///
/// assert_eq!(
/// Template::<&str, ()>::compile("User {a}").unwrap_err().kind,
/// SyntaxErrorKind::InvalidExpr(NotEmpty),
/// );
/// ```
;
/// An error which may occur while parsing a [`BoundedInt`] from a string.