tracing_formatters/
index.rs1use crate::value::Value;
2use core::fmt;
3use core::fmt::Display;
4use std::collections::BTreeMap;
5use std::ops;
6
7pub trait Index: private::Sealed {
8 #[doc(hidden)]
10 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
11
12 #[doc(hidden)]
14 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
15
16 #[doc(hidden)]
21 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
22}
23
24impl Index for usize {
25 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
26 match v {
27 Value::Array(vec) => vec.get(*self),
28 _ => None,
29 }
30 }
31 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
32 match v {
33 Value::Array(vec) => vec.get_mut(*self),
34 _ => None,
35 }
36 }
37 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
38 match v {
39 Value::Array(vec) => {
40 let len = vec.len();
41 vec.get_mut(*self).unwrap_or_else(|| {
42 panic!(
43 "cannot access index {} of JSON array of length {}",
44 self, len
45 )
46 })
47 }
48 _ => panic!("cannot access index {} of JSON {}", self, Type(v)),
49 }
50 }
51}
52
53impl Index for str {
54 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
55 match v {
56 Value::Map(map) => map.get(self),
57 _ => None,
58 }
59 }
60 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
61 match v {
62 Value::Map(map) => map.get_mut(self),
63 _ => None,
64 }
65 }
66 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
67 if let Value::Null = v {
68 *v = Value::Map(BTreeMap::new());
69 }
70 match v {
71 Value::Map(map) => map.entry(self.to_owned()).or_insert(Value::Null),
72 _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)),
73 }
74 }
75}
76
77impl Index for String {
78 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
79 self[..].index_into(v)
80 }
81 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
82 self[..].index_into_mut(v)
83 }
84 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
85 self[..].index_or_insert(v)
86 }
87}
88
89impl<'a, T> Index for &'a T
90where
91 T: ?Sized + Index,
92{
93 fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
94 (**self).index_into(v)
95 }
96 fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
97 (**self).index_into_mut(v)
98 }
99 fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
100 (**self).index_or_insert(v)
101 }
102}
103
104mod private {
106 pub trait Sealed {}
107 impl Sealed for usize {}
108 impl Sealed for str {}
109 impl Sealed for alloc::string::String {}
110 impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
111}
112
113struct Type<'a>(&'a Value);
115
116impl<'a> Display for Type<'a> {
117 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
118 match *self.0 {
119 Value::Null => formatter.write_str("null"),
120 Value::Bool(_) => formatter.write_str("boolean"),
121 Value::Int(_) => formatter.write_str("integer"),
122 Value::UInt(_) => formatter.write_str("uinteger"),
123 Value::Float(_) => formatter.write_str("float"),
124 Value::String(_) => formatter.write_str("string"),
125 Value::Array(_) => formatter.write_str("array"),
126 Value::Map(_) => formatter.write_str("object"),
127 }
128 }
129}
130
131impl<I> ops::Index<I> for Value
132where
133 I: Index,
134{
135 type Output = Value;
136
137 fn index(&self, index: I) -> &Value {
138 static NULL: Value = Value::Null;
139 index.index_into(self).unwrap_or(&NULL)
140 }
141}
142
143impl<I> ops::IndexMut<I> for Value
144where
145 I: Index,
146{
147 fn index_mut(&mut self, index: I) -> &mut Value {
148 index.index_or_insert(self)
149 }
150}