yerba 0.9.1-arm-linux-gnu → 0.10.0-arm-linux-gnu
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +60 -16
- data/exe/arm-linux-gnu/yerba +0 -0
- data/ext/yerba/include/yerba.h +67 -32
- data/ext/yerba/yerba.c +296 -186
- data/lib/yerba/3.2/yerba.so +0 -0
- data/lib/yerba/3.3/yerba.so +0 -0
- data/lib/yerba/3.4/yerba.so +0 -0
- data/lib/yerba/4.0/yerba.so +0 -0
- data/lib/yerba/collection.rb +4 -4
- data/lib/yerba/document.rb +134 -0
- data/lib/yerba/formatting.rb +1 -0
- data/lib/yerba/location.rb +8 -1
- data/lib/yerba/map.rb +16 -6
- data/lib/yerba/node.rb +41 -0
- data/lib/yerba/query_result.rb +33 -10
- data/lib/yerba/scalar.rb +29 -0
- data/lib/yerba/selector.rb +142 -0
- data/lib/yerba/sequence.rb +38 -33
- data/lib/yerba/version.rb +1 -1
- data/lib/yerba.rb +1 -0
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/src/commands/get.rs +12 -12
- data/rust/src/commands/init.rs +8 -8
- data/rust/src/commands/insert.rs +4 -18
- data/rust/src/commands/location.rs +2 -0
- data/rust/src/commands/mod.rs +34 -6
- data/rust/src/commands/move_item.rs +1 -1
- data/rust/src/commands/move_key.rs +8 -8
- data/rust/src/commands/rename.rs +1 -1
- data/rust/src/commands/selectors.rs +1 -1
- data/rust/src/commands/set.rs +14 -6
- data/rust/src/document/condition.rs +25 -25
- data/rust/src/document/delete.rs +57 -43
- data/rust/src/document/get.rs +91 -82
- data/rust/src/document/insert.rs +77 -77
- data/rust/src/document/mod.rs +138 -64
- data/rust/src/document/nodes.rs +162 -0
- data/rust/src/document/schema.rs +8 -8
- data/rust/src/document/set.rs +49 -26
- data/rust/src/document/sort.rs +54 -54
- data/rust/src/document/style.rs +50 -49
- data/rust/src/document/unique.rs +5 -5
- data/rust/src/error.rs +8 -4
- data/rust/src/ffi.rs +272 -102
- data/rust/src/json.rs +62 -2
- data/rust/src/lib.rs +2 -1
- data/rust/src/main.rs +2 -1
- data/rust/src/selector.rs +48 -7
- data/rust/src/syntax.rs +449 -56
- data/rust/src/validation.rs +5 -3
- data/rust/src/yerbafile.rs +124 -76
- metadata +4 -2
|
@@ -47,12 +47,12 @@ pub fn validate_item_condition(condition: &str) -> Result<(), YerbaError> {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
impl Document {
|
|
50
|
-
pub fn filter(&self,
|
|
50
|
+
pub fn filter(&self, selector: &str, condition: &str) -> Result<Vec<yaml_serde::Value>, YerbaError> {
|
|
51
51
|
validate_item_condition(condition)?;
|
|
52
52
|
|
|
53
53
|
Ok(
|
|
54
54
|
self
|
|
55
|
-
.navigate_all_compact(
|
|
55
|
+
.navigate_all_compact(selector)
|
|
56
56
|
.iter()
|
|
57
57
|
.filter(|node| self.evaluate_condition_on_node(node, condition))
|
|
58
58
|
.map(node_to_yaml_value)
|
|
@@ -60,14 +60,14 @@ impl Document {
|
|
|
60
60
|
)
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
pub fn filter_with_selectors(&self,
|
|
63
|
+
pub fn filter_with_selectors(&self, selector: &str, condition: &str) -> Result<Vec<(yaml_serde::Value, String, usize)>, YerbaError> {
|
|
64
64
|
validate_item_condition(condition)?;
|
|
65
65
|
|
|
66
66
|
let source = self.source_text();
|
|
67
67
|
|
|
68
68
|
Ok(
|
|
69
69
|
self
|
|
70
|
-
.navigate_all_compact(
|
|
70
|
+
.navigate_all_compact(selector)
|
|
71
71
|
.iter()
|
|
72
72
|
.filter(|node| self.evaluate_condition_on_node(node, condition))
|
|
73
73
|
.map(|node| {
|
|
@@ -88,13 +88,13 @@ impl Document {
|
|
|
88
88
|
None => return false,
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
let
|
|
91
|
+
let parsed = crate::selector::Selector::parse(&left);
|
|
92
92
|
|
|
93
|
-
if !
|
|
93
|
+
if !parsed.is_relative() {
|
|
94
94
|
return false;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
let target_nodes = navigate_from_node(node, &
|
|
97
|
+
let target_nodes = navigate_from_node(node, &parsed.to_selector_string());
|
|
98
98
|
let values: Vec<String> = target_nodes.iter().filter_map(extract_scalar_text).collect();
|
|
99
99
|
|
|
100
100
|
match operator {
|
|
@@ -138,8 +138,8 @@ impl Document {
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
pub fn evaluate_condition(&self,
|
|
142
|
-
if
|
|
141
|
+
pub fn evaluate_condition(&self, parent_selector: &str, condition: &str) -> Result<bool, YerbaError> {
|
|
142
|
+
if parent_selector.is_empty() {
|
|
143
143
|
validate_condition(condition)?;
|
|
144
144
|
} else {
|
|
145
145
|
validate_item_condition(condition)?;
|
|
@@ -152,55 +152,55 @@ impl Document {
|
|
|
152
152
|
None => return Ok(false),
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
let
|
|
156
|
-
let
|
|
155
|
+
let parsed = crate::selector::Selector::parse(&left);
|
|
156
|
+
let selector_string = parsed.to_selector_string();
|
|
157
157
|
|
|
158
|
-
let
|
|
159
|
-
|
|
158
|
+
let full_selector = if parent_selector.is_empty() {
|
|
159
|
+
selector_string
|
|
160
160
|
} else {
|
|
161
|
-
format!("{}.{}",
|
|
161
|
+
format!("{}.{}", parent_selector, selector_string)
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
-
let has_brackets = crate::selector::Selector::parse(&
|
|
164
|
+
let has_brackets = crate::selector::Selector::parse(&full_selector).has_brackets();
|
|
165
165
|
|
|
166
166
|
let result = match operator {
|
|
167
167
|
"==" => {
|
|
168
168
|
if has_brackets {
|
|
169
|
-
self.get_all(&
|
|
169
|
+
self.get_all(&full_selector).iter().any(|value| value == &right)
|
|
170
170
|
} else {
|
|
171
|
-
self.get(&
|
|
171
|
+
self.get(&full_selector).unwrap_or_default() == right
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
"!=" => {
|
|
175
175
|
if has_brackets {
|
|
176
|
-
self.get_all(&
|
|
176
|
+
self.get_all(&full_selector).iter().all(|value| value != &right)
|
|
177
177
|
} else {
|
|
178
|
-
self.get(&
|
|
178
|
+
self.get(&full_selector).unwrap_or_default() != right
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
"contains" => {
|
|
182
182
|
if has_brackets {
|
|
183
|
-
self.get_all(&
|
|
183
|
+
self.get_all(&full_selector).iter().any(|value| value == &right || value.contains(&right))
|
|
184
184
|
} else {
|
|
185
|
-
let items = self.get_sequence_values(&
|
|
185
|
+
let items = self.get_sequence_values(&full_selector);
|
|
186
186
|
|
|
187
187
|
if !items.is_empty() {
|
|
188
188
|
items.iter().any(|item| item == &right)
|
|
189
189
|
} else {
|
|
190
|
-
self.get(&
|
|
190
|
+
self.get(&full_selector).map(|value| value.contains(&right)).unwrap_or(false)
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
"not_contains" => {
|
|
195
195
|
if has_brackets {
|
|
196
|
-
self.get_all(&
|
|
196
|
+
self.get_all(&full_selector).iter().all(|value| value != &right && !value.contains(&right))
|
|
197
197
|
} else {
|
|
198
|
-
let items = self.get_sequence_values(&
|
|
198
|
+
let items = self.get_sequence_values(&full_selector);
|
|
199
199
|
|
|
200
200
|
if !items.is_empty() {
|
|
201
201
|
!items.iter().any(|item| item == &right)
|
|
202
202
|
} else {
|
|
203
|
-
self.get(&
|
|
203
|
+
self.get(&full_selector).map(|value| !value.contains(&right)).unwrap_or(true)
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
}
|
data/rust/src/document/delete.rs
CHANGED
|
@@ -1,70 +1,72 @@
|
|
|
1
1
|
use super::*;
|
|
2
2
|
|
|
3
3
|
impl Document {
|
|
4
|
-
pub fn rename(&mut self,
|
|
5
|
-
Self::
|
|
6
|
-
Self::
|
|
4
|
+
pub fn rename(&mut self, source_selector: &str, destination_selector: &str) -> Result<(), YerbaError> {
|
|
5
|
+
Self::validate_selector(source_selector)?;
|
|
6
|
+
Self::validate_selector(destination_selector)?;
|
|
7
7
|
|
|
8
|
-
let source_parent =
|
|
9
|
-
let destination_parent =
|
|
10
|
-
let destination_key =
|
|
8
|
+
let source_parent = source_selector.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
9
|
+
let destination_parent = destination_selector.rsplit_once('.').map(|(parent, _)| parent).unwrap_or("");
|
|
10
|
+
let destination_key = destination_selector.rsplit_once('.').map(|(_, key)| key).unwrap_or(destination_selector);
|
|
11
11
|
|
|
12
12
|
if source_parent == destination_parent {
|
|
13
|
-
let (
|
|
13
|
+
let (parent_selector, source_key) = source_selector.rsplit_once('.').unwrap_or(("", source_selector));
|
|
14
14
|
|
|
15
|
-
let parent_node = self.navigate(
|
|
16
|
-
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
15
|
+
let parent_node = self.navigate(parent_selector)?;
|
|
16
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(source_selector.to_string()))?;
|
|
17
17
|
|
|
18
|
-
let entry = find_entry_by_key(&map, source_key).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
19
|
-
let key_node = entry.key().ok_or_else(|| YerbaError::SelectorNotFound(
|
|
20
|
-
let key_token = find_scalar_token(key_node.syntax()).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
18
|
+
let entry = find_entry_by_key(&map, source_key).ok_or_else(|| YerbaError::SelectorNotFound(source_selector.to_string()))?;
|
|
19
|
+
let key_node = entry.key().ok_or_else(|| YerbaError::SelectorNotFound(source_selector.to_string()))?;
|
|
20
|
+
let key_token = find_scalar_token(key_node.syntax()).ok_or_else(|| YerbaError::SelectorNotFound(source_selector.to_string()))?;
|
|
21
21
|
let new_text = format_scalar_value(destination_key, key_token.kind());
|
|
22
22
|
|
|
23
23
|
self.replace_token(&key_token, &new_text)
|
|
24
24
|
} else {
|
|
25
|
-
let value = self
|
|
25
|
+
let value = self
|
|
26
|
+
.get(source_selector)
|
|
27
|
+
.ok_or_else(|| YerbaError::SelectorNotFound(source_selector.to_string()))?;
|
|
26
28
|
|
|
27
|
-
self.delete(
|
|
28
|
-
self.insert_into(
|
|
29
|
+
self.delete(source_selector)?;
|
|
30
|
+
self.insert_into(destination_selector, &value, InsertPosition::Last)
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
pub fn delete(&mut self,
|
|
33
|
-
Self::
|
|
34
|
-
self.refuse_flow_target(
|
|
34
|
+
pub fn delete(&mut self, selector: &str) -> Result<(), YerbaError> {
|
|
35
|
+
Self::validate_selector(selector)?;
|
|
36
|
+
self.refuse_flow_target(selector)?;
|
|
35
37
|
|
|
36
|
-
let
|
|
37
|
-
let segments =
|
|
38
|
-
let last_segment = segments.last().ok_or_else(|| YerbaError::SelectorNotFound(
|
|
39
|
-
let
|
|
38
|
+
let parsed = crate::selector::Selector::parse(selector);
|
|
39
|
+
let segments = parsed.segments();
|
|
40
|
+
let last_segment = segments.last().ok_or_else(|| YerbaError::SelectorNotFound(selector.to_string()))?;
|
|
41
|
+
let parent_selector = parsed.parent_selector();
|
|
40
42
|
|
|
41
43
|
match last_segment {
|
|
42
44
|
crate::selector::SelectorSegment::Key(last_key) => {
|
|
43
|
-
let has_wildcard =
|
|
44
|
-
let has_brackets =
|
|
45
|
+
let has_wildcard = parsed.has_wildcard();
|
|
46
|
+
let has_brackets = parsed.has_brackets();
|
|
45
47
|
|
|
46
|
-
if
|
|
47
|
-
let parent_node = self.navigate(&
|
|
48
|
-
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
48
|
+
if parent_selector.is_empty() && (!has_wildcard || !has_brackets) {
|
|
49
|
+
let parent_node = self.navigate(&parent_selector)?;
|
|
50
|
+
let map = find_block_map(&parent_node).ok_or_else(|| YerbaError::SelectorNotFound(selector.to_string()))?;
|
|
49
51
|
|
|
50
|
-
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
52
|
+
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(selector.to_string()))?;
|
|
51
53
|
|
|
52
54
|
return self.remove_map_entry(&entry);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
let parent_nodes = self.navigate_all_compact(&
|
|
57
|
+
let parent_nodes = self.navigate_all_compact(&parent_selector);
|
|
56
58
|
|
|
57
59
|
if parent_nodes.is_empty() {
|
|
58
60
|
if has_wildcard {
|
|
59
61
|
return Ok(());
|
|
60
62
|
}
|
|
61
63
|
|
|
62
|
-
return Err(YerbaError::SelectorNotFound(
|
|
64
|
+
return Err(YerbaError::SelectorNotFound(selector.to_string()));
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
if parent_nodes.len() == 1 && (!has_wildcard || !has_brackets) {
|
|
66
|
-
let map = find_block_map(&parent_nodes[0]).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
67
|
-
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(
|
|
68
|
+
let map = find_block_map(&parent_nodes[0]).ok_or_else(|| YerbaError::SelectorNotFound(selector.to_string()))?;
|
|
69
|
+
let entry = find_entry_by_key(&map, last_key).ok_or_else(|| YerbaError::SelectorNotFound(selector.to_string()))?;
|
|
68
70
|
|
|
69
71
|
if map.entries().count() == 1 {
|
|
70
72
|
return self.collapse_to_empty_flow_map(&parent_nodes[0]);
|
|
@@ -88,19 +90,31 @@ impl Document {
|
|
|
88
90
|
self.apply_edits(edits)
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
crate::selector::SelectorSegment::Index(index) => self.remove_at(&
|
|
92
|
-
crate::selector::SelectorSegment::
|
|
93
|
+
crate::selector::SelectorSegment::Index(index) => self.remove_at(&parent_selector, *index),
|
|
94
|
+
crate::selector::SelectorSegment::IndexFromEnd(_) => {
|
|
95
|
+
let parent_node = self.navigate(&parent_selector)?;
|
|
96
|
+
let length = find_block_sequence(&parent_node)
|
|
97
|
+
.map(|sequence| sequence.entries().count())
|
|
98
|
+
.or_else(|| find_flow_sequence(&parent_node).map(|sequence| flow_sequence_entries(&sequence).len()))
|
|
99
|
+
.ok_or_else(|| YerbaError::NotASequence(parent_selector.clone()))?;
|
|
100
|
+
let index = last_segment
|
|
101
|
+
.sequence_index(length)
|
|
102
|
+
.ok_or_else(|| YerbaError::SelectorNotFound(selector.to_string()))?;
|
|
103
|
+
|
|
104
|
+
self.remove_at(&parent_selector, index)
|
|
105
|
+
}
|
|
106
|
+
crate::selector::SelectorSegment::AllItems | crate::selector::SelectorSegment::AllKeys => Err(YerbaError::SelectorNotFound(selector.to_string())),
|
|
93
107
|
}
|
|
94
108
|
}
|
|
95
109
|
|
|
96
|
-
pub fn remove(&mut self,
|
|
97
|
-
let current_node = self.navigate(
|
|
110
|
+
pub fn remove(&mut self, selector: &str, value: &str) -> Result<(), YerbaError> {
|
|
111
|
+
let current_node = self.navigate(selector)?;
|
|
98
112
|
|
|
99
113
|
if find_flow_sequence(¤t_node).is_some() {
|
|
100
|
-
return Err(YerbaError::FlowCollectionNotWritable(
|
|
114
|
+
return Err(YerbaError::FlowCollectionNotWritable(selector.to_string()));
|
|
101
115
|
}
|
|
102
116
|
|
|
103
|
-
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(
|
|
117
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(selector.to_string()))?;
|
|
104
118
|
|
|
105
119
|
let target_entry = sequence
|
|
106
120
|
.entries()
|
|
@@ -111,7 +125,7 @@ impl Document {
|
|
|
111
125
|
.map(|text| text == value)
|
|
112
126
|
.unwrap_or(false)
|
|
113
127
|
})
|
|
114
|
-
.ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'",
|
|
128
|
+
.ok_or_else(|| YerbaError::SelectorNotFound(format!("{} item '{}'", selector, value)))?;
|
|
115
129
|
|
|
116
130
|
if sequence.entries().count() == 1 {
|
|
117
131
|
return self.collapse_to_empty_flow_sequence(¤t_node);
|
|
@@ -120,12 +134,12 @@ impl Document {
|
|
|
120
134
|
self.remove_node(target_entry.syntax())
|
|
121
135
|
}
|
|
122
136
|
|
|
123
|
-
pub fn remove_at(&mut self,
|
|
124
|
-
Self::
|
|
137
|
+
pub fn remove_at(&mut self, selector: &str, index: usize) -> Result<(), YerbaError> {
|
|
138
|
+
Self::validate_selector(selector)?;
|
|
125
139
|
|
|
126
|
-
let current_node = self.navigate(
|
|
140
|
+
let current_node = self.navigate(selector)?;
|
|
127
141
|
|
|
128
|
-
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(
|
|
142
|
+
let sequence = find_block_sequence(¤t_node).ok_or_else(|| YerbaError::NotASequence(selector.to_string()))?;
|
|
129
143
|
|
|
130
144
|
let entries: Vec<_> = sequence.entries().collect();
|
|
131
145
|
|