json_pointer_simd/
value.rs

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