hocon_rs/raw/
raw_object.rs1use crate::join;
2use crate::raw::field::ObjectField;
3use crate::raw::raw_string::RawString;
4use crate::raw::raw_value::RawValue;
5use crate::{path::Path, value::Value};
6use derive_more::{Constructor, Deref, DerefMut};
7use std::fmt::{Display, Formatter};
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, Deref, DerefMut, Constructor)]
10pub struct RawObject(pub Vec<ObjectField>);
11
12impl RawObject {
13 pub fn from_entries<I>(entries: Vec<(RawString, RawValue)>) -> Self
14 where
15 I: IntoIterator<Item = (RawString, RawValue)>,
16 {
17 let fields = entries
18 .into_iter()
19 .map(|(k, v)| ObjectField::key_value(k, v))
20 .collect();
21 Self::new(fields)
22 }
23
24 pub fn remove_by_path(&mut self, path: &Path) -> Option<ObjectField> {
25 let mut remove_index = None;
26 for (index, field) in self.iter_mut().enumerate().rev() {
27 match field {
28 ObjectField::Inclusion { inclusion, .. } => {
29 if let Some(obj) = &mut inclusion.val {
30 return obj.remove_by_path(path);
31 }
32 }
33 ObjectField::KeyValue { key, value, .. } => {
34 let k = &key.as_path();
35 if path.starts_with1(k) {
36 match path.sub_path(k.len()) {
37 None => {
38 remove_index = Some(index);
39 break;
40 }
41 Some(sub_path) => {
42 if let RawValue::Object(obj) = value {
43 return obj.remove_by_path(sub_path);
44 }
45 }
46 }
47 }
48 }
49 ObjectField::NewlineComment(_) => {}
50 }
51 }
52 remove_index.map(|index| self.remove(index))
53 }
54
55 pub fn remove_all_by_path(&mut self, path: &Path) -> Vec<ObjectField> {
58 let mut results = vec![];
59 let mut remove_indices = vec![]; for (index, field) in self.iter_mut().enumerate().rev() {
61 match field {
62 ObjectField::Inclusion { inclusion, .. } => {
63 if let Some(obj) = &mut inclusion.val {
64 results.extend(obj.remove_all_by_path(path));
65 }
66 }
67 ObjectField::KeyValue { key, value, .. } => {
68 let k = &key.as_path();
69 if path.starts_with1(k) {
70 match path.sub_path(k.len()) {
71 None => {
72 remove_indices.push(index);
73 }
74 Some(sub_path) => {
75 if let RawValue::Object(obj) = value {
76 results.extend(obj.remove_all_by_path(sub_path));
77 }
78 }
79 }
80 }
81 }
82 ObjectField::NewlineComment(_) => {}
83 }
84 }
85 for idx in remove_indices {
86 results.push(self.remove(idx));
87 }
88 results
89 }
90
91 pub fn get_by_path(&self, path: &Path) -> Option<&RawValue> {
92 for field in self.iter().rev() {
93 match field {
94 ObjectField::Inclusion { inclusion, .. } => {
95 if let Some(obj) = &inclusion.val {
96 return obj.get_by_path(path);
97 }
98 }
99 ObjectField::KeyValue { key, value, .. } => {
100 let k = &key.as_path();
101 if path.starts_with1(k) {
102 match path.sub_path(k.len()) {
103 None => return Some(value),
104 Some(sub_path) => {
105 if let RawValue::Object(obj) = value {
106 return obj.get_by_path(sub_path);
107 }
108 }
109 }
110 }
111 }
112 ObjectField::NewlineComment(_) => {}
113 }
114 }
115 None
116 }
117
118 pub fn get_by_path_mut(&mut self, path: &Path) -> Option<&mut RawValue> {
119 for field in self.iter_mut().rev() {
120 match field {
121 ObjectField::Inclusion { inclusion, .. } => {
122 if let Some(obj) = &mut inclusion.val {
123 return obj.get_by_path_mut(path);
124 }
125 }
126 ObjectField::KeyValue { key, value, .. } => {
127 let k = &key.as_path();
128 if path.starts_with1(k) {
129 match path.sub_path(k.len()) {
130 None => return Some(value),
131 Some(sub_path) => {
132 if let RawValue::Object(obj) = value {
133 return obj.get_by_path_mut(sub_path);
134 }
135 }
136 }
137 }
138 }
139 ObjectField::NewlineComment(_) => {}
140 }
141 }
142 None
143 }
144
145 pub(crate) fn merge(mut left: Self, right: Self) -> Self {
153 left.0.extend(right.0);
154 left
155 }
156}
157
158impl Display for RawObject {
159 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
160 write!(f, "{{")?;
161 join(self.iter(), ", ", f)?;
162 write!(f, "}}")?;
163 Ok(())
164 }
165}
166
167impl From<Value> for RawValue {
168 fn from(val: Value) -> Self {
169 match val {
170 Value::Object(object) => {
171 let len = object.len();
172 let fields =
173 object
174 .into_iter()
175 .fold(Vec::with_capacity(len), |mut acc, (key, value)| {
176 let field = ObjectField::key_value(key, value);
177 acc.push(field);
178 acc
179 });
180 RawValue::Object(RawObject::new(fields))
181 }
182 Value::Array(array) => RawValue::array(array.into_iter().map(Into::into).collect()),
183 Value::Boolean(boolean) => RawValue::Boolean(boolean),
184 Value::Null => RawValue::Null,
185 Value::String(string) => RawValue::String(string.into()),
186 Value::Number(number) => RawValue::Number(number),
187 }
188 }
189}