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