wezterm_dynamic/
object.rs1use crate::Value;
2use std::cmp::Ordering;
3use std::collections::BTreeMap;
4use std::ops::{Deref, DerefMut};
5
6#[derive(Copy, Clone, Debug, PartialEq, Hash, Eq, Ord, PartialOrd)]
12pub enum BorrowedKey<'a> {
13 Value(&'a Value),
14 Str(&'a str),
15}
16
17pub trait ObjectKeyTrait {
18 fn key<'k>(&'k self) -> BorrowedKey<'k>;
19}
20
21impl ObjectKeyTrait for Value {
22 fn key<'k>(&'k self) -> BorrowedKey<'k> {
23 match self {
24 Value::String(s) => BorrowedKey::Str(s.as_str()),
25 v => BorrowedKey::Value(v),
26 }
27 }
28}
29
30impl<'a> ObjectKeyTrait for BorrowedKey<'a> {
31 fn key<'k>(&'k self) -> BorrowedKey<'k> {
32 *self
33 }
34}
35
36impl<'a> std::borrow::Borrow<dyn ObjectKeyTrait + 'a> for Value {
37 fn borrow(&self) -> &(dyn ObjectKeyTrait + 'a) {
38 self
39 }
40}
41
42impl<'a> PartialEq for (dyn ObjectKeyTrait + 'a) {
43 fn eq(&self, other: &Self) -> bool {
44 self.key().eq(&other.key())
45 }
46}
47
48impl<'a> Eq for (dyn ObjectKeyTrait + 'a) {}
49
50impl<'a> PartialOrd for (dyn ObjectKeyTrait + 'a) {
51 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
52 self.key().partial_cmp(&other.key())
53 }
54}
55
56impl<'a> Ord for (dyn ObjectKeyTrait + 'a) {
57 fn cmp(&self, other: &Self) -> Ordering {
58 self.key().cmp(&other.key())
59 }
60}
61
62impl<'a> std::hash::Hash for (dyn ObjectKeyTrait + 'a) {
63 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
64 self.key().hash(state)
65 }
66}
67
68#[derive(Clone, Default, PartialEq, Eq, Hash)]
69pub struct Object {
70 inner: BTreeMap<Value, Value>,
71}
72
73impl Object {
74 pub fn get_by_str(&self, field_name: &str) -> Option<&Value> {
75 self.inner
76 .get(&BorrowedKey::Str(field_name) as &dyn ObjectKeyTrait)
77 }
78}
79
80impl std::fmt::Debug for Object {
81 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
82 self.inner.fmt(fmt)
83 }
84}
85
86impl Ord for Object {
87 fn cmp(&self, other: &Self) -> Ordering {
88 let self_ptr = self as *const Self;
89 let other_ptr = other as *const Self;
90 self_ptr.cmp(&other_ptr)
91 }
92}
93
94impl PartialOrd for Object {
95 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
96 Some(self.cmp(other))
97 }
98}
99
100impl Drop for Object {
101 fn drop(&mut self) {
102 for (_, child) in std::mem::take(&mut self.inner) {
103 crate::drop::safely(child);
104 }
105 }
106}
107
108impl From<BTreeMap<Value, Value>> for Object {
109 fn from(inner: BTreeMap<Value, Value>) -> Self {
110 Self { inner }
111 }
112}
113
114impl Deref for Object {
115 type Target = BTreeMap<Value, Value>;
116
117 fn deref(&self) -> &Self::Target {
118 &self.inner
119 }
120}
121
122impl DerefMut for Object {
123 fn deref_mut(&mut self) -> &mut Self::Target {
124 &mut self.inner
125 }
126}
127
128fn take(object: Object) -> BTreeMap<Value, Value> {
129 let object = core::mem::ManuallyDrop::new(object);
130 unsafe { core::ptr::read(&object.inner) }
131}
132
133impl IntoIterator for Object {
134 type Item = (Value, Value);
135 type IntoIter = <BTreeMap<Value, Value> as IntoIterator>::IntoIter;
136
137 fn into_iter(self) -> Self::IntoIter {
138 take(self).into_iter()
139 }
140}
141
142impl<'a> IntoIterator for &'a Object {
143 type Item = (&'a Value, &'a Value);
144 type IntoIter = <&'a BTreeMap<Value, Value> as IntoIterator>::IntoIter;
145
146 fn into_iter(self) -> Self::IntoIter {
147 self.iter()
148 }
149}
150
151impl<'a> IntoIterator for &'a mut Object {
152 type Item = (&'a Value, &'a mut Value);
153 type IntoIter = <&'a mut BTreeMap<Value, Value> as IntoIterator>::IntoIter;
154
155 fn into_iter(self) -> Self::IntoIter {
156 self.iter_mut()
157 }
158}
159
160impl FromIterator<(Value, Value)> for Object {
161 fn from_iter<I>(iter: I) -> Self
162 where
163 I: IntoIterator<Item = (Value, Value)>,
164 {
165 Object {
166 inner: BTreeMap::from_iter(iter),
167 }
168 }
169}