/rust/registry/src/index.crates.io-1949cf8c6b5b557f/iri-string-0.7.9/src/template.rs
Line | Count | Source |
1 | | //! Processor for [RFC 6570] URI Template. |
2 | | //! |
3 | | //! [RFC 6570]: https://www.rfc-editor.org/rfc/rfc6570.html |
4 | | //! |
5 | | //! # Usage |
6 | | //! |
7 | | //! 1. Prepare a template. |
8 | | //! * You can create a template as [`UriTemplateStr`] |
9 | | #![cfg_attr( |
10 | | feature = "alloc", |
11 | | doc = " type (borrowed) or [`UriTemplateString`] type (owned)." |
12 | | )] |
13 | | #![cfg_attr(not(feature = "alloc"), doc = " type.")] |
14 | | //! 2. Prepare a context. |
15 | | //! * Create a value of type that implements [`Context`] trait. |
16 | | #![cfg_attr( |
17 | | feature = "alloc", |
18 | | doc = " * Or, if you use [`SimpleContext`], insert key-value pairs into it." |
19 | | )] |
20 | | //! 3. Expand. |
21 | | //! * Pass the context to [`UriTemplateStr::expand`] method of the template. |
22 | | //! 4. Use the result. |
23 | | //! * Returned [`Expanded`] object can be directly printed since it |
24 | | //! implements [`Display`][`core::fmt::Display`] trait. Or, you can call |
25 | | //! `.to_string()` method of the `alloc::string::ToString` trait to |
26 | | //! convert it to a `String`. |
27 | | //! |
28 | | //! # Examples |
29 | | //! |
30 | | //! ## Custom context type |
31 | | //! |
32 | | //! For details, see [the documentation of `context` module][`context`]. |
33 | | //! |
34 | | //! ``` |
35 | | //! # use iri_string::template::Error; |
36 | | //! use core::fmt; |
37 | | //! use iri_string::spec::{IriSpec, Spec, UriSpec}; |
38 | | //! use iri_string::template::UriTemplateStr; |
39 | | //! use iri_string::template::context::{Context, VarName, Visitor}; |
40 | | //! |
41 | | //! struct UserInfo { |
42 | | //! username: &'static str, |
43 | | //! utf8_available: bool, |
44 | | //! } |
45 | | //! |
46 | | //! impl Context for UserInfo { |
47 | | //! fn visit<V: Visitor>( |
48 | | //! &self, |
49 | | //! visitor: V, |
50 | | //! ) -> V::Result { |
51 | | //! match visitor.var_name().as_str() { |
52 | | //! "username" => visitor.visit_string(self.username), |
53 | | //! "utf8" => { |
54 | | //! if self.utf8_available { |
55 | | //! // U+2713 CHECK MARK |
56 | | //! visitor.visit_string("\u{2713}") |
57 | | //! } else { |
58 | | //! visitor.visit_undefined() |
59 | | //! } |
60 | | //! } |
61 | | //! _ => visitor.visit_undefined() |
62 | | //! } |
63 | | //! } |
64 | | //! } |
65 | | //! |
66 | | //! let context = UserInfo { |
67 | | //! username: "foo", |
68 | | //! utf8_available: true, |
69 | | //! }; |
70 | | //! |
71 | | //! let template = UriTemplateStr::new("/users/{username}{?utf8}")?; |
72 | | //! |
73 | | //! # #[cfg(feature = "alloc")] { |
74 | | //! assert_eq!( |
75 | | //! template.expand::<UriSpec, _>(&context)?.to_string(), |
76 | | //! "/users/foo?utf8=%E2%9C%93" |
77 | | //! ); |
78 | | //! assert_eq!( |
79 | | //! template.expand::<IriSpec, _>(&context)?.to_string(), |
80 | | //! "/users/foo?utf8=\u{2713}" |
81 | | //! ); |
82 | | //! # } |
83 | | //! # Ok::<_, Error>(()) |
84 | | //! ``` |
85 | | //! |
86 | | //! ## `SimpleContext` type (enabled by `alloc` feature flag) |
87 | | //! |
88 | | //! ``` |
89 | | //! # use iri_string::template::Error; |
90 | | //! # #[cfg(feature = "alloc")] { |
91 | | //! use iri_string::spec::{IriSpec, UriSpec}; |
92 | | //! use iri_string::template::UriTemplateStr; |
93 | | //! use iri_string::template::simple_context::SimpleContext; |
94 | | //! |
95 | | //! let mut context = SimpleContext::new(); |
96 | | //! context.insert("username", "foo"); |
97 | | //! // U+2713 CHECK MARK |
98 | | //! context.insert("utf8", "\u{2713}"); |
99 | | //! |
100 | | //! let template = UriTemplateStr::new("/users/{username}{?utf8}")?; |
101 | | //! |
102 | | //! assert_eq!( |
103 | | //! template.expand::<UriSpec, _>(&context)?.to_string(), |
104 | | //! "/users/foo?utf8=%E2%9C%93" |
105 | | //! ); |
106 | | //! assert_eq!( |
107 | | //! template.expand::<IriSpec, _>(&context)?.to_string(), |
108 | | //! "/users/foo?utf8=\u{2713}" |
109 | | //! ); |
110 | | //! # } |
111 | | //! # Ok::<_, Error>(()) |
112 | | //! ``` |
113 | | //! |
114 | | #![cfg_attr( |
115 | | feature = "alloc", |
116 | | doc = "[`SimpleContext`]: `simple_context::SimpleContext`" |
117 | | )] |
118 | | mod components; |
119 | | pub mod context; |
120 | | mod error; |
121 | | mod expand; |
122 | | mod parser; |
123 | | #[cfg(feature = "alloc")] |
124 | | pub mod simple_context; |
125 | | mod string; |
126 | | |
127 | | pub use self::context::{Context, DynamicContext}; |
128 | | #[cfg(feature = "alloc")] |
129 | | pub use self::error::CreationError; |
130 | | pub use self::error::Error; |
131 | | pub use self::expand::Expanded; |
132 | | #[cfg(feature = "alloc")] |
133 | | pub use self::string::UriTemplateString; |
134 | | pub use self::string::{UriTemplateStr, UriTemplateVariables}; |
135 | | |
136 | | /// Deprecated old name of [`template::context::VarName`]. |
137 | | /// |
138 | | /// [`template::context::VarName`]: `components::VarName` |
139 | | #[deprecated( |
140 | | since = "0.7.1", |
141 | | note = "renamed (moved) to `template::context::VarName`" |
142 | | )] |
143 | | pub type VarName<'a> = self::components::VarName<'a>; |
144 | | |
145 | | /// Variable value type. |
146 | | #[derive(Debug, Clone, Copy)] |
147 | | enum ValueType { |
148 | | /// Undefined (i.e. null). |
149 | | Undefined, |
150 | | /// String value. |
151 | | String, |
152 | | /// List. |
153 | | List, |
154 | | /// Associative array. |
155 | | Assoc, |
156 | | } |
157 | | |
158 | | impl ValueType { |
159 | | /// Returns the value type for an undefined variable. |
160 | | #[inline] |
161 | | #[must_use] |
162 | 0 | pub const fn undefined() -> Self { |
163 | 0 | ValueType::Undefined |
164 | 0 | } |
165 | | |
166 | | /// Returns the value type for a string variable. |
167 | | #[inline] |
168 | | #[must_use] |
169 | 0 | pub const fn string() -> Self { |
170 | 0 | ValueType::String |
171 | 0 | } |
172 | | |
173 | | /// Returns the value type for an empty list variable. |
174 | | #[inline] |
175 | | #[must_use] |
176 | 0 | pub const fn empty_list() -> Self { |
177 | 0 | ValueType::Undefined |
178 | 0 | } |
179 | | |
180 | | /// Returns the value type for a nonempty list variable. |
181 | | #[inline] |
182 | | #[must_use] |
183 | 0 | pub const fn nonempty_list() -> Self { |
184 | 0 | ValueType::List |
185 | 0 | } |
186 | | |
187 | | /// Returns the value type for an empty associative array variable. |
188 | | #[inline] |
189 | | #[must_use] |
190 | 0 | pub const fn empty_assoc() -> Self { |
191 | 0 | ValueType::Undefined |
192 | 0 | } |
193 | | |
194 | | /// Returns the value type for a nonempty associative array variable. |
195 | | #[inline] |
196 | | #[must_use] |
197 | 0 | pub const fn nonempty_assoc() -> Self { |
198 | 0 | ValueType::Assoc |
199 | 0 | } |
200 | | } |