Coverage Report

Created: 2026-01-30 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}