json_pointer_simd/
owned.rs

1use std::ops::{Index, IndexMut};
2use crate::{JsonPointer, JsonPointerTarget, IndexError};
3use simd_json::value::owned::Value;
4
5/// 
6/// Implement getting for SIMD JSON Owned values
7///
8impl JsonPointerTarget for Value {
9
10    /// Attempts to get a reference to a value from the given JSON value,
11    /// returning an error if it can't be found.
12    fn get<'value, S: AsRef<str>, C: AsRef<[S]>>(&'value self, ptr: &JsonPointer<S,C>) -> Result<&'value Self, IndexError> {
13        ptr.ref_toks.as_ref().iter().try_fold(self, |val, tok| {
14            let tok = tok.as_ref();
15            match *val {
16                Value::Object(ref obj) => obj.get(tok).ok_or_else(|| IndexError::NoSuchKey(tok.to_owned())),
17                Value::Array(ref arr) => {
18                    let idx = if tok == "-" {
19                        arr.len()
20                    } else if let Ok(idx) = tok.parse() {
21                        idx
22                    } else {
23                        return Err(IndexError::NoSuchKey(tok.to_owned()));
24                    };
25                    arr.get(idx).ok_or(IndexError::OutOfBounds(idx))
26                },
27                _ => Err(IndexError::NotIndexable),
28            }
29        })
30    }
31
32    /// Attempts to get a mutable reference to a value from the given JSON
33    /// value, returning an error if it can't be found.
34    fn get_mut<'value, S: AsRef<str>, C: AsRef<[S]>>(&'value mut self, ptr: &JsonPointer<S,C>) -> Result<&'value mut Self, IndexError> {
35        ptr.ref_toks.as_ref().iter().try_fold(self, |val, tok| {
36            let tok = tok.as_ref();
37            match *val {
38                Value::Object(ref mut obj) => obj.get_mut(tok).ok_or_else(|| IndexError::NoSuchKey(tok.to_owned())),
39                Value::Array(ref mut arr) => {
40                    let idx = if tok == "-" {
41                        arr.len()
42                    } else if let Ok(idx) = tok.parse() {
43                        idx
44                    } else {
45                        return Err(IndexError::NoSuchKey(tok.to_owned()));
46                    };
47                    arr.get_mut(idx).ok_or(IndexError::OutOfBounds(idx))
48                },
49                _ => Err(IndexError::NotIndexable),
50            }
51        })
52    }
53
54    /// Attempts to get an owned value from the given JSON value, returning an
55    /// error if it can't be found.
56    fn get_owned<'value, S: AsRef<str>, C: AsRef<[S]>>(self, ptr: &JsonPointer<S,C>) -> Result<Self, IndexError> {
57        ptr.ref_toks.as_ref().iter().try_fold(self, |val, tok| {
58            let tok = tok.as_ref();
59            match val {
60                Value::Object(mut obj) => obj.remove(tok).ok_or_else(|| IndexError::NoSuchKey(tok.to_owned())),
61                Value::Array(mut arr) => {
62                    let idx = if tok == "-" {
63                        arr.len()
64                    } else if let Ok(idx) = tok.parse() {
65                        idx
66                    } else {
67                        return Err(IndexError::NoSuchKey(tok.to_owned()));
68                    };
69                    if idx >= arr.len() {
70                        Err(IndexError::OutOfBounds(idx))
71                    } else {
72                        Ok(arr.swap_remove(idx))
73                    }
74                },
75                _ => Err(IndexError::NotIndexable),
76            }
77        })
78    }
79}
80
81impl<'a, S: AsRef<str>, C: AsRef<[S]>> Index<&'a JsonPointer<S, C>> for Value {
82    type Output = Value;
83    fn index(&self, ptr: &'a JsonPointer<S, C>) -> &Value {
84        self.get(ptr).unwrap()
85    }
86}
87
88impl<'a, S: AsRef<str>, C: AsRef<[S]>> IndexMut<&'a JsonPointer<S, C>> for Value {
89    fn index_mut(&mut self, ptr: &'a JsonPointer<S, C>) -> &mut Value {
90        self.get_mut(ptr).unwrap()
91    }
92}