Skip to content

Commit 511c27b

Browse files
committed
Add enum RawKind and is_* to RawValue
1 parent 4aa05b9 commit 511c27b

File tree

1 file changed

+143
-0
lines changed

1 file changed

+143
-0
lines changed

src/raw.rs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,149 @@ impl RawValue {
227227
pub fn get(&self) -> &str {
228228
&self.json
229229
}
230+
231+
/// Returns the kind of JSON value contained within.
232+
fn kind(&self) -> RawKind {
233+
let first = self
234+
.json
235+
.as_bytes()
236+
.first()
237+
.expect("The `str` contained in `RawValue` can`t be an empty");
238+
239+
// `RawValue` has whitespace stripped so we know the first char is non-whitespace.
240+
// `RawValue` is also valid JSON so the only possible set of chars that can come next
241+
// are `[0-9]` or `[-fnt"[{]`.
242+
match *first {
243+
b'n' => RawKind::Null,
244+
b't' | b'f' => RawKind::Bool,
245+
b'"' => RawKind::String,
246+
b'[' => RawKind::Array,
247+
b'{' => RawKind::Object,
248+
// A `RawValue` is already known to be valid, the only other possibility for
249+
// valid JSON is that this is a number
250+
_ => RawKind::Number,
251+
}
252+
}
253+
254+
/// Returns true if the `Value` is a Null. Returns false otherwise.
255+
///
256+
/// ```
257+
/// # use serde_json::json;
258+
/// #
259+
/// let v = json!({ "a": null, "b": false });
260+
/// let v = serde_json::value::to_raw_value(v).unwrap();
261+
///
262+
/// assert!(v["a"].is_null());
263+
///
264+
/// // The boolean `false` is not null.
265+
/// assert!(!v["b"].is_null());
266+
/// ```
267+
fn is_null(&self) -> bool {
268+
matches!(self.kind(), RawKind::Null)
269+
}
270+
271+
/// Returns true if the `Value` is a Boolean. Returns false otherwise.
272+
///
273+
/// ```
274+
/// # use serde_json::json;
275+
/// #
276+
/// let v = json!({ "a": false, "b": "false" });
277+
/// let v = serde_json::value::to_raw_value(v).unwrap();
278+
///
279+
/// assert!(v["a"].is_boolean());
280+
///
281+
/// // The string `"false"` is a string, not a boolean.
282+
/// assert!(!v["b"].is_boolean());
283+
/// ```
284+
fn is_boolean(&self) -> bool {
285+
matches!(self.kind(), RawKind::Bool)
286+
}
287+
288+
/// Returns true if the `Value` is a Number. Returns false otherwise.
289+
///
290+
/// ```
291+
/// # use serde_json::json;
292+
/// #
293+
/// let v = json!({ "a": 1, "b": "2" });
294+
/// let v = serde_json::value::to_raw_value(v).unwrap();
295+
///
296+
/// assert!(v["a"].is_number());
297+
///
298+
/// // The string `"2"` is a string, not a number.
299+
/// assert!(!v["b"].is_number());
300+
/// ```
301+
fn is_number(&self) -> bool {
302+
matches!(self.kind(), RawKind::Number)
303+
}
304+
305+
/// Returns true if the `Value` is a String. Returns false otherwise.
306+
///
307+
/// ```
308+
/// # use serde_json::json;
309+
/// #
310+
/// let v = json!({ "a": "some string", "b": false });
311+
/// let v = serde_json::value::to_raw_value(v).unwrap();
312+
///
313+
/// assert!(v["a"].is_string());
314+
///
315+
/// // The boolean `false` is not a string.
316+
/// assert!(!v["b"].is_string());
317+
/// ```
318+
fn is_string(&self) -> bool {
319+
matches!(self.kind(), RawKind::String)
320+
}
321+
322+
/// Returns true if the `Value` is an Array. Returns false otherwise.
323+
///
324+
/// ```
325+
/// # use serde_json::json;
326+
/// #
327+
/// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } });
328+
/// let obj = serde_json::value::to_raw_value(obj).unwrap();
329+
///
330+
/// assert!(obj["a"].is_array());
331+
///
332+
/// // an object, not an array
333+
/// assert!(!obj["b"].is_array());
334+
/// ```
335+
fn is_array(&self) -> bool {
336+
matches!(self.kind(), RawKind::Array)
337+
}
338+
339+
/// Returns true if the `Value` is an Object. Returns false otherwise.
340+
///
341+
/// ```
342+
/// # use serde_json::json;
343+
/// #
344+
/// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] });
345+
/// let obj = serde_json::value::to_raw_value(obj).unwrap();
346+
///
347+
/// assert!(obj.is_object());
348+
/// assert!(obj["a"].is_object());
349+
///
350+
/// // array, not an object
351+
/// assert!(!obj["b"].is_object());
352+
/// ```
353+
fn is_object(&self) -> bool {
354+
matches!(self.kind(), RawKind::Object)
355+
}
356+
}
357+
358+
// A kind of JSON value the `RawValue` contains.
359+
#[derive(Debug, Copy, Clone)]
360+
pub enum RawKind {
361+
/// Represents a JSON null value.
362+
Null,
363+
/// Represents a JSON boolean.
364+
Bool,
365+
/// Represents a JSON number, whether integer or floating point.
366+
Number,
367+
/// Represents a JSON string.
368+
String,
369+
/// Represents a JSON array.
370+
Array,
371+
/// Represents a JSON object.
372+
Object,
230373
}
231374

232375
impl From<Box<RawValue>> for Box<str> {

0 commit comments

Comments
 (0)