]>
git.proxmox.com Git - rustc.git/blob - src/vendor/serde_json/src/macros.rs
bb595f908ec158b85c704acd4f1802cdba714ceb
1 // Copyright 2017 Serde Developers
3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6 // option. This file may not be copied, modified, or distributed
7 // except according to those terms.
9 /// Construct a `serde_json::Value` from a JSON literal.
13 /// # extern crate serde_json;
16 /// let value = json!({
29 /// Variables or expressions can be interpolated into the JSON literal. Any type
30 /// interpolated into an array element or object value must implement Serde's
31 /// `Serialize` trait, while any type interpolated into a object key must
32 /// implement `Into<String>`. If the `Serialize` implementation of the
33 /// interpolated type decides to fail, or if the interpolated type contains a
34 /// map with non-string keys, the `json!` macro will panic.
38 /// # extern crate serde_json;
42 /// let features = vec!["serde", "json"];
44 /// let value = json!({
46 /// "success": code == 200,
48 /// features[0]: features[1]
54 /// Trailing commas are allowed inside both arrays and objects.
58 /// # extern crate serde_json;
61 /// let value = json!([
71 // Hide distracting implementation details from the generated rustdoc.
73 json_internal
!($
($json
)+)
77 // Rocket relies on this because they export their own `json!` with a different
78 // doc comment than ours, and various Rust bugs prevent them from calling our
79 // `json!` from their `json!` so they call `json_internal!` directly. Check with
80 // @SergioBenitez before making breaking changes to this macro.
82 // Changes are fine as long as `json_internal!` does not call any new helper
83 // macros and can still be invoked as `json_internal!($($json)+)`.
86 macro_rules
! json_internal
{
87 //////////////////////////////////////////////////////////////////////////
88 // TT muncher for parsing the inside of an array [...]. Produces a vec![...]
91 // Must be invoked as: json_internal!(@array [] $($tt)*)
92 //////////////////////////////////////////////////////////////////////////
94 // Done with trailing comma.
95 (@array
[$
($elems
:expr
,)*]) => {
99 // Done without trailing comma.
100 (@array
[$
($elems
:expr
),*]) => {
104 // Next element is `null`.
105 (@array
[$
($elems
:expr
,)*] null $
($rest
:tt
)*) => {
106 json_internal
!(@array
[$
($elems
,)* json_internal
!(null
)] $
($rest
)*)
109 // Next element is `true`.
110 (@array
[$
($elems
:expr
,)*] true $
($rest
:tt
)*) => {
111 json_internal
!(@array
[$
($elems
,)* json_internal
!(true)] $
($rest
)*)
114 // Next element is `false`.
115 (@array
[$
($elems
:expr
,)*] false $
($rest
:tt
)*) => {
116 json_internal
!(@array
[$
($elems
,)* json_internal
!(false)] $
($rest
)*)
119 // Next element is an array.
120 (@array
[$
($elems
:expr
,)*] [$
($array
:tt
)*] $
($rest
:tt
)*) => {
121 json_internal
!(@array
[$
($elems
,)* json_internal
!([$
($array
)*])] $
($rest
)*)
124 // Next element is a map.
125 (@array
[$
($elems
:expr
,)*] {$($map:tt)*} $
($rest
:tt
)*) => {
126 json_internal
!(@array
[$
($elems
,)* json_internal
!({$($map)*}
)] $
($rest
)*)
129 // Next element is an expression followed by comma.
130 (@array
[$
($elems
:expr
,)*] $next
:expr
, $
($rest
:tt
)*) => {
131 json_internal
!(@array
[$
($elems
,)* json_internal
!($next
),] $
($rest
)*)
134 // Last element is an expression with no trailing comma.
135 (@array
[$
($elems
:expr
,)*] $last
:expr
) => {
136 json_internal
!(@array
[$
($elems
,)* json_internal
!($last
)])
139 // Comma after the most recent element.
140 (@array
[$
($elems
:expr
),*] , $
($rest
:tt
)*) => {
141 json_internal
!(@array
[$
($elems
,)*] $
($rest
)*)
144 //////////////////////////////////////////////////////////////////////////
145 // TT muncher for parsing the inside of an object {...}. Each entry is
146 // inserted into the given map variable.
148 // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*))
150 // We require two copies of the input tokens so that we can match on one
151 // copy and trigger errors on the other copy.
152 //////////////////////////////////////////////////////////////////////////
155 (@object $object
:ident () () ()) => {}
;
157 // Insert the current entry followed by trailing comma.
158 (@object $object
:ident
[$
($key
:tt
)+] ($value
:expr
) , $
($rest
:tt
)*) => {
159 $object
.insert(($
($key
)+).into(), $value
);
160 json_internal
!(@object $
object () ($
($rest
)*) ($
($rest
)*));
163 // Insert the last entry without trailing comma.
164 (@object $object
:ident
[$
($key
:tt
)+] ($value
:expr
)) => {
165 $object
.insert(($
($key
)+).into(), $value
);
168 // Next value is `null`.
169 (@object $object
:ident ($
($key
:tt
)+) (: null $
($rest
:tt
)*) $copy
:tt
) => {
170 json_internal
!(@object $object
[$
($key
)+] (json_internal
!(null
)) $
($rest
)*);
173 // Next value is `true`.
174 (@object $object
:ident ($
($key
:tt
)+) (: true $
($rest
:tt
)*) $copy
:tt
) => {
175 json_internal
!(@object $object
[$
($key
)+] (json_internal
!(true)) $
($rest
)*);
178 // Next value is `false`.
179 (@object $object
:ident ($
($key
:tt
)+) (: false $
($rest
:tt
)*) $copy
:tt
) => {
180 json_internal
!(@object $object
[$
($key
)+] (json_internal
!(false)) $
($rest
)*);
183 // Next value is an array.
184 (@object $object
:ident ($
($key
:tt
)+) (: [$
($array
:tt
)*] $
($rest
:tt
)*) $copy
:tt
) => {
185 json_internal
!(@object $object
[$
($key
)+] (json_internal
!([$
($array
)*])) $
($rest
)*);
188 // Next value is a map.
189 (@object $object
:ident ($
($key
:tt
)+) (: {$($map:tt)*} $
($rest
:tt
)*) $copy
:tt
) => {
190 json_internal
!(@object $object
[$
($key
)+] (json_internal
!({$($map)*}
)) $
($rest
)*);
193 // Next value is an expression followed by comma.
194 (@object $object
:ident ($
($key
:tt
)+) (: $value
:expr
, $
($rest
:tt
)*) $copy
:tt
) => {
195 json_internal
!(@object $object
[$
($key
)+] (json_internal
!($value
)) , $
($rest
)*);
198 // Last value is an expression with no trailing comma.
199 (@object $object
:ident ($
($key
:tt
)+) (: $value
:expr
) $copy
:tt
) => {
200 json_internal
!(@object $object
[$
($key
)+] (json_internal
!($value
)));
203 // Missing value for last entry. Trigger a reasonable error message.
204 (@object $object
:ident ($
($key
:tt
)+) (:) $copy
:tt
) => {
205 // "unexpected end of macro invocation"
209 // Missing colon and value for last entry. Trigger a reasonable error
211 (@object $object
:ident ($
($key
:tt
)+) () $copy
:tt
) => {
212 // "unexpected end of macro invocation"
216 // Misplaced colon. Trigger a reasonable error message.
217 (@object $object
:ident () (: $
($rest
:tt
)*) ($colon
:tt $
($copy
:tt
)*)) => {
218 // Takes no arguments so "no rules expected the token `:`".
219 unimplemented
!($colon
);
222 // Found a comma inside a key. Trigger a reasonable error message.
223 (@object $object
:ident ($
($key
:tt
)*) (, $
($rest
:tt
)*) ($comma
:tt $
($copy
:tt
)*)) => {
224 // Takes no arguments so "no rules expected the token `,`".
225 unimplemented
!($comma
);
228 // Key is fully parenthesized. This avoids clippy double_parens false
229 // positives because the parenthesization may be necessary here.
230 (@object $object
:ident () (($key
:expr
) : $
($rest
:tt
)*) $copy
:tt
) => {
231 json_internal
!(@object $
object ($key
) (: $
($rest
)*) (: $
($rest
)*));
234 // Munch a token into the current key.
235 (@object $object
:ident ($
($key
:tt
)*) ($tt
:tt $
($rest
:tt
)*) $copy
:tt
) => {
236 json_internal
!(@object $
object ($
($key
)* $tt
) ($
($rest
)*) ($
($rest
)*));
239 //////////////////////////////////////////////////////////////////////////
240 // The main implementation.
242 // Must be invoked as: json_internal!($($json)+)
243 //////////////////////////////////////////////////////////////////////////
250 $
crate::Value
::Bool(true)
254 $
crate::Value
::Bool(false)
258 $
crate::Value
::Array(vec
![])
261 ([ $
($tt
:tt
)+ ]) => {
262 $
crate::Value
::Array(json_internal
!(@array
[] $
($tt
)+))
266 $
crate::Value
::Object($
crate::Map
::new())
269 ({ $($tt:tt)+ }
) => {
270 $
crate::Value
::Object({
271 let mut object
= $
crate::Map
::new();
272 json_internal
!(@object
object () ($
($tt
)+) ($
($tt
)+));
277 // Any Serialize type: numbers, strings, struct literals, variables etc.
278 // Must be below every other rule.
280 $
crate::to_value(&$other
).unwrap()