yerba 0.3.0-arm-linux-gnu → 0.4.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 +90 -8
- data/exe/arm-linux-gnu/yerba +0 -0
- data/ext/yerba/extconf.rb +22 -3
- data/ext/yerba/include/yerba.h +19 -9
- data/ext/yerba/yerba.c +83 -24
- 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 +35 -0
- data/lib/yerba/document.rb +16 -0
- data/lib/yerba/sequence.rb +169 -1
- data/lib/yerba/version.rb +1 -1
- data/rust/Cargo.lock +1 -1
- data/rust/Cargo.toml +1 -1
- data/rust/cbindgen.toml +1 -0
- data/rust/rustfmt.toml +1 -1
- data/rust/src/commands/blank_lines.rs +1 -4
- data/rust/src/commands/directives.rs +61 -0
- data/rust/src/commands/get.rs +5 -22
- data/rust/src/commands/mod.rs +5 -10
- data/rust/src/commands/quote_style.rs +12 -6
- data/rust/src/commands/selectors.rs +3 -19
- data/rust/src/commands/sort.rs +22 -157
- data/rust/src/didyoumean.rs +2 -4
- data/rust/src/document/condition.rs +139 -0
- data/rust/src/document/delete.rs +91 -0
- data/rust/src/document/get.rs +262 -0
- data/rust/src/document/insert.rs +314 -0
- data/rust/src/document/mod.rs +784 -0
- data/rust/src/document/set.rs +90 -0
- data/rust/src/document/sort.rs +607 -0
- data/rust/src/document/style.rs +473 -0
- data/rust/src/error.rs +24 -6
- data/rust/src/ffi.rs +208 -520
- data/rust/src/json.rs +1 -7
- data/rust/src/lib.rs +88 -2
- data/rust/src/quote_style.rs +83 -7
- data/rust/src/selector.rs +2 -7
- data/rust/src/syntax.rs +41 -21
- data/rust/src/yerbafile.rs +39 -18
- metadata +10 -2
- data/rust/src/document.rs +0 -2304
data/rust/src/ffi.rs
CHANGED
|
@@ -12,10 +12,8 @@ use std::ffi::{CStr, CString};
|
|
|
12
12
|
use std::os::raw::c_char;
|
|
13
13
|
use std::ptr;
|
|
14
14
|
|
|
15
|
-
use yaml_parser::SyntaxKind;
|
|
16
|
-
|
|
17
|
-
use crate::selector::Selector;
|
|
18
15
|
use crate::syntax::{detect_yaml_type, YerbaValueType};
|
|
16
|
+
use crate::NodeType;
|
|
19
17
|
use crate::{Document, InsertPosition, QuoteStyle};
|
|
20
18
|
|
|
21
19
|
#[repr(C)]
|
|
@@ -52,15 +50,6 @@ pub struct YerbaTypedList {
|
|
|
52
50
|
pub length: usize,
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
#[repr(C)]
|
|
56
|
-
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
57
|
-
pub enum YerbaNodeType {
|
|
58
|
-
Scalar = 0,
|
|
59
|
-
Map = 1,
|
|
60
|
-
Sequence = 2,
|
|
61
|
-
NotFound = 3,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
53
|
#[repr(C)]
|
|
65
54
|
pub struct YerbaParseResult {
|
|
66
55
|
pub document: *mut Document,
|
|
@@ -80,7 +69,7 @@ pub struct YerbaLocation {
|
|
|
80
69
|
#[repr(C)]
|
|
81
70
|
pub struct YerbaGetResult {
|
|
82
71
|
pub is_list: bool,
|
|
83
|
-
pub node_type:
|
|
72
|
+
pub node_type: NodeType,
|
|
84
73
|
pub single: YerbaTypedValue,
|
|
85
74
|
pub list: YerbaTypedList,
|
|
86
75
|
pub location: YerbaLocation,
|
|
@@ -89,6 +78,72 @@ pub struct YerbaGetResult {
|
|
|
89
78
|
pub error: *mut c_char,
|
|
90
79
|
}
|
|
91
80
|
|
|
81
|
+
impl YerbaGetResult {
|
|
82
|
+
fn empty() -> Self {
|
|
83
|
+
YerbaGetResult {
|
|
84
|
+
is_list: false,
|
|
85
|
+
node_type: NodeType::NotFound,
|
|
86
|
+
single: YerbaTypedValue {
|
|
87
|
+
text: ptr::null_mut(),
|
|
88
|
+
value_type: YerbaValueType::Null,
|
|
89
|
+
},
|
|
90
|
+
list: YerbaTypedList {
|
|
91
|
+
json: ptr::null_mut(),
|
|
92
|
+
length: 0,
|
|
93
|
+
},
|
|
94
|
+
location: EMPTY_LOCATION,
|
|
95
|
+
key_name: ptr::null_mut(),
|
|
96
|
+
key_location: EMPTY_LOCATION,
|
|
97
|
+
error: ptr::null_mut(),
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fn with_error(error: &str) -> Self {
|
|
102
|
+
let mut result = Self::empty();
|
|
103
|
+
|
|
104
|
+
result.error = CString::new(error).unwrap_or_default().into_raw();
|
|
105
|
+
|
|
106
|
+
result
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
fn with_location(mut self, location: YerbaLocation, key_name: *mut c_char, key_location: YerbaLocation) -> Self {
|
|
110
|
+
self.location = location;
|
|
111
|
+
self.key_name = key_name;
|
|
112
|
+
self.key_location = key_location;
|
|
113
|
+
|
|
114
|
+
self
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
fn scalar(mut self, text: &str, value_type: YerbaValueType) -> Self {
|
|
118
|
+
self.node_type = NodeType::Scalar;
|
|
119
|
+
|
|
120
|
+
self.single = YerbaTypedValue {
|
|
121
|
+
text: CString::new(text).unwrap_or_default().into_raw(),
|
|
122
|
+
value_type,
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
self
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
fn list(mut self, json: &str, length: usize) -> Self {
|
|
129
|
+
self.is_list = true;
|
|
130
|
+
self.node_type = NodeType::Sequence;
|
|
131
|
+
|
|
132
|
+
self.list = YerbaTypedList {
|
|
133
|
+
json: CString::new(json).unwrap_or_default().into_raw(),
|
|
134
|
+
length,
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
self
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fn with_node_type(mut self, node_type: NodeType) -> Self {
|
|
141
|
+
self.node_type = node_type;
|
|
142
|
+
|
|
143
|
+
self
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
92
147
|
#[no_mangle]
|
|
93
148
|
pub unsafe extern "C" fn yerba_document_parse_file(path: *const c_char) -> YerbaParseResult {
|
|
94
149
|
if path.is_null() {
|
|
@@ -98,19 +153,17 @@ pub unsafe extern "C" fn yerba_document_parse_file(path: *const c_char) -> Yerba
|
|
|
98
153
|
};
|
|
99
154
|
}
|
|
100
155
|
|
|
101
|
-
let
|
|
156
|
+
let file_path = match CStr::from_ptr(path).to_str() {
|
|
102
157
|
Ok(string) => string,
|
|
103
158
|
Err(e) => {
|
|
104
159
|
return YerbaParseResult {
|
|
105
160
|
document: ptr::null_mut(),
|
|
106
|
-
error: CString::new(format!("Invalid UTF-8 in path: {}", e))
|
|
107
|
-
.unwrap_or_default()
|
|
108
|
-
.into_raw(),
|
|
161
|
+
error: CString::new(format!("Invalid UTF-8 in path: {}", e)).unwrap_or_default().into_raw(),
|
|
109
162
|
}
|
|
110
163
|
}
|
|
111
164
|
};
|
|
112
165
|
|
|
113
|
-
match Document::parse_file(
|
|
166
|
+
match Document::parse_file(file_path) {
|
|
114
167
|
Ok(document) => YerbaParseResult {
|
|
115
168
|
document: Box::into_raw(Box::new(document)),
|
|
116
169
|
error: ptr::null_mut(),
|
|
@@ -137,9 +190,7 @@ pub unsafe extern "C" fn yerba_document_parse(content: *const c_char) -> YerbaPa
|
|
|
137
190
|
Err(e) => {
|
|
138
191
|
return YerbaParseResult {
|
|
139
192
|
document: ptr::null_mut(),
|
|
140
|
-
error: CString::new(format!("Invalid UTF-8: {}", e))
|
|
141
|
-
.unwrap_or_default()
|
|
142
|
-
.into_raw(),
|
|
193
|
+
error: CString::new(format!("Invalid UTF-8: {}", e)).unwrap_or_default().into_raw(),
|
|
143
194
|
}
|
|
144
195
|
}
|
|
145
196
|
};
|
|
@@ -157,28 +208,6 @@ pub unsafe extern "C" fn yerba_document_parse(content: *const c_char) -> YerbaPa
|
|
|
157
208
|
}
|
|
158
209
|
}
|
|
159
210
|
|
|
160
|
-
fn compute_location(source: &str, start_offset: usize, end_offset: usize) -> YerbaLocation {
|
|
161
|
-
let start = start_offset.min(source.len());
|
|
162
|
-
let end = end_offset.min(source.len());
|
|
163
|
-
|
|
164
|
-
let before_start = &source[..start];
|
|
165
|
-
let start_line = before_start.chars().filter(|c| *c == '\n').count() + 1;
|
|
166
|
-
let start_column = start - before_start.rfind('\n').map(|p| p + 1).unwrap_or(0);
|
|
167
|
-
|
|
168
|
-
let before_end = &source[..end];
|
|
169
|
-
let end_line = before_end.chars().filter(|c| *c == '\n').count() + 1;
|
|
170
|
-
let end_column = end - before_end.rfind('\n').map(|p| p + 1).unwrap_or(0);
|
|
171
|
-
|
|
172
|
-
YerbaLocation {
|
|
173
|
-
start_offset: start,
|
|
174
|
-
end_offset: end,
|
|
175
|
-
start_line,
|
|
176
|
-
start_column,
|
|
177
|
-
end_line,
|
|
178
|
-
end_column,
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
211
|
const EMPTY_LOCATION: YerbaLocation = YerbaLocation {
|
|
183
212
|
start_offset: 0,
|
|
184
213
|
end_offset: 0,
|
|
@@ -198,173 +227,71 @@ pub unsafe extern "C" fn yerba_document_free(document: *mut Document) {
|
|
|
198
227
|
#[no_mangle]
|
|
199
228
|
pub unsafe extern "C" fn yerba_document_get(document: *const Document, path: *const c_char) -> YerbaGetResult {
|
|
200
229
|
let document = &*document;
|
|
201
|
-
let
|
|
230
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
202
231
|
|
|
203
|
-
let
|
|
204
|
-
|
|
205
|
-
if let Err(e) = Document::validate_path(path_string) {
|
|
206
|
-
return YerbaGetResult {
|
|
207
|
-
is_list: false,
|
|
208
|
-
node_type: YerbaNodeType::NotFound,
|
|
209
|
-
single: YerbaTypedValue {
|
|
210
|
-
text: ptr::null_mut(),
|
|
211
|
-
value_type: YerbaValueType::Null,
|
|
212
|
-
},
|
|
213
|
-
list: YerbaTypedList {
|
|
214
|
-
json: ptr::null_mut(),
|
|
215
|
-
length: 0,
|
|
216
|
-
},
|
|
217
|
-
key_name: ptr::null_mut(),
|
|
218
|
-
key_location: EMPTY_LOCATION,
|
|
219
|
-
location: EMPTY_LOCATION,
|
|
220
|
-
error: CString::new(e.to_string()).unwrap_or_default().into_raw(),
|
|
221
|
-
};
|
|
232
|
+
if let Err(e) = Document::validate_path(selector_string) {
|
|
233
|
+
return YerbaGetResult::with_error(&e.to_string());
|
|
222
234
|
}
|
|
223
235
|
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
let
|
|
227
|
-
Ok(node) => {
|
|
228
|
-
let range = node.text_range();
|
|
229
|
-
let location = compute_location(&source, range.start().into(), range.end().into());
|
|
236
|
+
let info = document.get_node_info(selector_string);
|
|
237
|
+
let location = location_to_ffi(info.location);
|
|
238
|
+
let key_location = location_to_ffi(info.key_location);
|
|
230
239
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
.and_then(|parent| {
|
|
234
|
-
use rowan::ast::AstNode;
|
|
235
|
-
use yaml_parser::ast::BlockMapEntry;
|
|
236
|
-
|
|
237
|
-
BlockMapEntry::cast(parent).and_then(|entry| {
|
|
238
|
-
entry.key().and_then(|key_node| {
|
|
239
|
-
let key_text = crate::syntax::extract_scalar_text(key_node.syntax())?;
|
|
240
|
-
let key_range = key_node.syntax().text_range();
|
|
241
|
-
let key_location = compute_location(&source, key_range.start().into(), key_range.end().into());
|
|
242
|
-
|
|
243
|
-
Some((key_text, key_location))
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
})
|
|
247
|
-
.map(|(name, location)| (Some(name), location))
|
|
248
|
-
.unwrap_or((None, EMPTY_LOCATION));
|
|
249
|
-
|
|
250
|
-
(location, key_text, key_location)
|
|
251
|
-
}
|
|
252
|
-
Err(_) => (EMPTY_LOCATION, None, EMPTY_LOCATION),
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
let key_name_pointer = key_text
|
|
240
|
+
let key_name = info
|
|
241
|
+
.key_name
|
|
256
242
|
.map(|name| CString::new(name).unwrap_or_default().into_raw())
|
|
257
243
|
.unwrap_or(ptr::null_mut());
|
|
258
244
|
|
|
259
|
-
|
|
260
|
-
let values = document.get_all_typed(path_string);
|
|
245
|
+
let base = YerbaGetResult::empty().with_location(location, key_name, key_location);
|
|
261
246
|
|
|
262
|
-
|
|
247
|
+
if info.is_list {
|
|
248
|
+
let typed: Vec<serde_json::Value> = info
|
|
249
|
+
.list_values
|
|
263
250
|
.iter()
|
|
264
|
-
.map(|
|
|
251
|
+
.map(|value| {
|
|
265
252
|
serde_json::json!({
|
|
266
|
-
"text":
|
|
267
|
-
"type": detect_yaml_type(
|
|
253
|
+
"text": value.text,
|
|
254
|
+
"type": detect_yaml_type(value) as u8
|
|
268
255
|
})
|
|
269
256
|
})
|
|
270
257
|
.collect();
|
|
271
258
|
|
|
272
259
|
let json = serde_json::to_string(&typed).unwrap_or_else(|_| "[]".to_string());
|
|
273
|
-
let length = values.len();
|
|
274
260
|
|
|
275
|
-
|
|
276
|
-
is_list: true,
|
|
277
|
-
node_type: YerbaNodeType::Sequence,
|
|
278
|
-
single: YerbaTypedValue {
|
|
279
|
-
text: ptr::null_mut(),
|
|
280
|
-
value_type: YerbaValueType::Null,
|
|
281
|
-
},
|
|
282
|
-
list: YerbaTypedList {
|
|
283
|
-
json: CString::new(json).unwrap_or_default().into_raw(),
|
|
284
|
-
length,
|
|
285
|
-
},
|
|
286
|
-
location,
|
|
287
|
-
key_name: key_name_pointer,
|
|
288
|
-
key_location,
|
|
289
|
-
error: ptr::null_mut(),
|
|
290
|
-
}
|
|
261
|
+
base.list(&json, info.list_values.len())
|
|
291
262
|
} else {
|
|
292
|
-
match
|
|
293
|
-
Some(scalar) =>
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
YerbaGetResult {
|
|
297
|
-
is_list: false,
|
|
298
|
-
node_type: YerbaNodeType::Scalar,
|
|
299
|
-
single: YerbaTypedValue {
|
|
300
|
-
text: CString::new(scalar.text).unwrap_or_default().into_raw(),
|
|
301
|
-
value_type: vtype,
|
|
302
|
-
},
|
|
303
|
-
list: YerbaTypedList {
|
|
304
|
-
json: ptr::null_mut(),
|
|
305
|
-
length: 0,
|
|
306
|
-
},
|
|
307
|
-
location,
|
|
308
|
-
key_name: key_name_pointer,
|
|
309
|
-
key_location,
|
|
310
|
-
error: ptr::null_mut(),
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
None => {
|
|
315
|
-
use rowan::ast::AstNode;
|
|
316
|
-
use yaml_parser::ast::{BlockMap, BlockSeq};
|
|
317
|
-
|
|
318
|
-
let node_type = match document.navigate(path_string) {
|
|
319
|
-
Ok(node) => {
|
|
320
|
-
if node.children().any(|child| BlockSeq::can_cast(child.kind())) {
|
|
321
|
-
YerbaNodeType::Sequence
|
|
322
|
-
} else if node.children().any(|child| BlockMap::can_cast(child.kind())) {
|
|
323
|
-
YerbaNodeType::Map
|
|
324
|
-
} else if node.descendants().any(|child| BlockSeq::can_cast(child.kind())) {
|
|
325
|
-
YerbaNodeType::Sequence
|
|
326
|
-
} else if node.descendants().any(|child| BlockMap::can_cast(child.kind())) {
|
|
327
|
-
YerbaNodeType::Map
|
|
328
|
-
} else {
|
|
329
|
-
YerbaNodeType::NotFound
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
Err(_) => YerbaNodeType::NotFound,
|
|
333
|
-
};
|
|
334
|
-
|
|
335
|
-
YerbaGetResult {
|
|
336
|
-
is_list: false,
|
|
337
|
-
node_type,
|
|
338
|
-
single: YerbaTypedValue {
|
|
339
|
-
text: ptr::null_mut(),
|
|
340
|
-
value_type: YerbaValueType::Null,
|
|
341
|
-
},
|
|
342
|
-
list: YerbaTypedList {
|
|
343
|
-
json: ptr::null_mut(),
|
|
344
|
-
length: 0,
|
|
345
|
-
},
|
|
346
|
-
location,
|
|
347
|
-
key_name: key_name_pointer,
|
|
348
|
-
key_location,
|
|
349
|
-
error: ptr::null_mut(),
|
|
350
|
-
}
|
|
351
|
-
}
|
|
263
|
+
match info.value {
|
|
264
|
+
Some(scalar) => base.scalar(&scalar.text, detect_yaml_type(&scalar)),
|
|
265
|
+
None => base.with_node_type(info.node_type),
|
|
352
266
|
}
|
|
353
267
|
}
|
|
354
268
|
}
|
|
355
269
|
|
|
270
|
+
fn location_to_ffi(location: crate::Location) -> YerbaLocation {
|
|
271
|
+
YerbaLocation {
|
|
272
|
+
start_offset: location.start_offset,
|
|
273
|
+
end_offset: location.end_offset,
|
|
274
|
+
start_line: location.start_line,
|
|
275
|
+
start_column: location.start_column,
|
|
276
|
+
end_line: location.end_line,
|
|
277
|
+
end_column: location.end_column,
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
356
281
|
/// Caller must free with yerba_string_free.
|
|
357
282
|
#[no_mangle]
|
|
358
283
|
pub unsafe extern "C" fn yerba_document_get_value(document: *const Document, path: *const c_char) -> *mut c_char {
|
|
359
284
|
let document = &*document;
|
|
360
|
-
let
|
|
285
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
361
286
|
|
|
362
|
-
match document.get_value(
|
|
287
|
+
match document.get_value(selector_string) {
|
|
363
288
|
Some(value) => {
|
|
364
289
|
let json = crate::json::yaml_to_json(&value);
|
|
365
290
|
let json_string = serde_json::to_string(&json).unwrap_or_else(|_| "null".to_string());
|
|
291
|
+
|
|
366
292
|
CString::new(json_string).unwrap_or_default().into_raw()
|
|
367
293
|
}
|
|
294
|
+
|
|
368
295
|
None => ptr::null_mut(),
|
|
369
296
|
}
|
|
370
297
|
}
|
|
@@ -373,9 +300,9 @@ pub unsafe extern "C" fn yerba_document_get_value(document: *const Document, pat
|
|
|
373
300
|
#[no_mangle]
|
|
374
301
|
pub unsafe extern "C" fn yerba_document_get_values(document: *const Document, path: *const c_char) -> *mut c_char {
|
|
375
302
|
let document = &*document;
|
|
376
|
-
let
|
|
303
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
377
304
|
|
|
378
|
-
let values = document.get_values(
|
|
305
|
+
let values = document.get_values(selector_string);
|
|
379
306
|
let json_values: Vec<serde_json::Value> = values.iter().map(crate::json::yaml_to_json).collect();
|
|
380
307
|
let json_string = serde_json::to_string(&json_values).unwrap_or_else(|_| "[]".to_string());
|
|
381
308
|
|
|
@@ -383,50 +310,40 @@ pub unsafe extern "C" fn yerba_document_get_values(document: *const Document, pa
|
|
|
383
310
|
}
|
|
384
311
|
|
|
385
312
|
#[no_mangle]
|
|
386
|
-
pub unsafe extern "C" fn yerba_document_get_quote_style(document: *const Document, path: *const c_char) ->
|
|
313
|
+
pub unsafe extern "C" fn yerba_document_get_quote_style(document: *const Document, path: *const c_char) -> *mut c_char {
|
|
387
314
|
let document = &*document;
|
|
388
|
-
let
|
|
389
|
-
|
|
390
|
-
match document.get_typed(path_string) {
|
|
391
|
-
Some(scalar) => match scalar.kind {
|
|
392
|
-
SyntaxKind::PLAIN_SCALAR => 0,
|
|
393
|
-
SyntaxKind::SINGLE_QUOTED_SCALAR => 1,
|
|
394
|
-
SyntaxKind::DOUBLE_QUOTED_SCALAR => 2,
|
|
395
|
-
_ => -1,
|
|
396
|
-
},
|
|
315
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
397
316
|
|
|
398
|
-
|
|
317
|
+
match document.get_quote_style(selector_string) {
|
|
318
|
+
Some(style) => {
|
|
319
|
+
let ruby_style = style.replace('-', "_");
|
|
320
|
+
|
|
321
|
+
CString::new(ruby_style).map(|s| s.into_raw()).unwrap_or(std::ptr::null_mut())
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
None => std::ptr::null_mut(),
|
|
399
325
|
}
|
|
400
326
|
}
|
|
401
327
|
|
|
402
328
|
#[no_mangle]
|
|
403
|
-
pub unsafe extern "C" fn yerba_document_set_quote_style(
|
|
404
|
-
document: *mut Document,
|
|
405
|
-
path: *const c_char,
|
|
406
|
-
style: i32,
|
|
407
|
-
) -> YerbaResult {
|
|
329
|
+
pub unsafe extern "C" fn yerba_document_set_quote_style(document: *mut Document, path: *const c_char, style: *const c_char) -> YerbaResult {
|
|
408
330
|
let document = &mut *document;
|
|
409
|
-
let
|
|
331
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
332
|
+
let style_string = &CStr::from_ptr(style).to_str().unwrap_or("").replace('_', "-");
|
|
410
333
|
|
|
411
|
-
let quote_style = match
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
2 => QuoteStyle::Double,
|
|
415
|
-
_ => return YerbaResult::err("Invalid quote style (use 0=plain, 1=single, 2=double)"),
|
|
334
|
+
let quote_style = match style_string.parse::<QuoteStyle>() {
|
|
335
|
+
Ok(style) => style,
|
|
336
|
+
Err(e) => return YerbaResult::err(&e),
|
|
416
337
|
};
|
|
417
338
|
|
|
418
|
-
match document.
|
|
419
|
-
Ok(
|
|
339
|
+
match document.enforce_quotes_at("e_style, Some(selector_string)) {
|
|
340
|
+
Ok(_warnings) => YerbaResult::ok(),
|
|
420
341
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
421
342
|
}
|
|
422
343
|
}
|
|
423
344
|
|
|
424
345
|
#[no_mangle]
|
|
425
|
-
pub unsafe extern "C" fn yerba_document_evaluate_condition(
|
|
426
|
-
document: *const Document,
|
|
427
|
-
parent_path: *const c_char,
|
|
428
|
-
condition: *const c_char,
|
|
429
|
-
) -> bool {
|
|
346
|
+
pub unsafe extern "C" fn yerba_document_evaluate_condition(document: *const Document, parent_path: *const c_char, condition: *const c_char) -> bool {
|
|
430
347
|
let document = &*document;
|
|
431
348
|
let parent = CStr::from_ptr(parent_path).to_str().unwrap_or("");
|
|
432
349
|
let cond = CStr::from_ptr(condition).to_str().unwrap_or("");
|
|
@@ -436,62 +353,22 @@ pub unsafe extern "C" fn yerba_document_evaluate_condition(
|
|
|
436
353
|
#[no_mangle]
|
|
437
354
|
pub unsafe extern "C" fn yerba_document_exists(document: *const Document, path: *const c_char) -> bool {
|
|
438
355
|
let document = &*document;
|
|
439
|
-
let
|
|
440
|
-
document.exists(
|
|
356
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
357
|
+
document.exists(selector_string)
|
|
441
358
|
}
|
|
442
359
|
|
|
443
360
|
#[no_mangle]
|
|
444
|
-
pub unsafe extern "C" fn yerba_document_find(
|
|
445
|
-
document: *const Document,
|
|
446
|
-
path: *const c_char,
|
|
447
|
-
condition: *const c_char,
|
|
448
|
-
select: *const c_char,
|
|
449
|
-
) -> *mut c_char {
|
|
361
|
+
pub unsafe extern "C" fn yerba_document_find(document: *const Document, path: *const c_char, condition: *const c_char, select: *const c_char) -> *mut c_char {
|
|
450
362
|
let document = &*document;
|
|
451
|
-
let
|
|
452
|
-
|
|
453
|
-
let condition_str = if condition.is_null() {
|
|
454
|
-
None
|
|
455
|
-
} else {
|
|
456
|
-
CStr::from_ptr(condition).to_str().ok()
|
|
457
|
-
};
|
|
458
|
-
|
|
459
|
-
let _select_string = if select.is_null() {
|
|
460
|
-
None
|
|
461
|
-
} else {
|
|
462
|
-
CStr::from_ptr(select).to_str().ok()
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
let values = match condition_str {
|
|
466
|
-
Some(cond) => document.filter(path_string, cond),
|
|
467
|
-
None => document.get_values(path_string),
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
let select_fields: Option<Vec<&str>> = _select_string.map(|s| s.split(',').collect());
|
|
471
|
-
|
|
472
|
-
let mut results: Vec<serde_json::Value> = Vec::new();
|
|
363
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
473
364
|
|
|
474
|
-
|
|
475
|
-
match &select_fields {
|
|
476
|
-
Some(fields) => {
|
|
477
|
-
let mut result = serde_json::Map::new();
|
|
365
|
+
let condition_string = if condition.is_null() { None } else { CStr::from_ptr(condition).to_str().ok() };
|
|
478
366
|
|
|
479
|
-
|
|
480
|
-
let json_value = crate::json::resolve_select_field(value, field);
|
|
481
|
-
let json_key = crate::json::select_field_key(field);
|
|
482
|
-
|
|
483
|
-
result.insert(json_key, json_value);
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
results.push(serde_json::Value::Object(result));
|
|
487
|
-
}
|
|
488
|
-
None => {
|
|
489
|
-
results.push(crate::json::yaml_to_json(value));
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
367
|
+
let select_string = if select.is_null() { None } else { CStr::from_ptr(select).to_str().ok() };
|
|
493
368
|
|
|
369
|
+
let results = document.find_items(selector_string, condition_string, select_string);
|
|
494
370
|
let json = serde_json::to_string_pretty(&results).unwrap_or_else(|_| "[]".to_string());
|
|
371
|
+
|
|
495
372
|
CString::new(json).unwrap_or_default().into_raw()
|
|
496
373
|
}
|
|
497
374
|
|
|
@@ -504,15 +381,15 @@ pub unsafe extern "C" fn yerba_document_set(
|
|
|
504
381
|
all: bool,
|
|
505
382
|
) -> YerbaResult {
|
|
506
383
|
let document = &mut *document;
|
|
507
|
-
let
|
|
384
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
508
385
|
let value_string = CStr::from_ptr(value).to_str().unwrap_or("");
|
|
509
386
|
|
|
510
387
|
let result = if all {
|
|
511
|
-
document.set_all(
|
|
388
|
+
document.set_all(selector_string, value_string)
|
|
512
389
|
} else {
|
|
513
390
|
match value_type {
|
|
514
|
-
YerbaValueType::String => document.set(
|
|
515
|
-
_ => document.set_plain(
|
|
391
|
+
YerbaValueType::String => document.set(selector_string, value_string),
|
|
392
|
+
_ => document.set_plain(selector_string, value_string),
|
|
516
393
|
}
|
|
517
394
|
};
|
|
518
395
|
|
|
@@ -532,7 +409,7 @@ pub unsafe extern "C" fn yerba_document_insert(
|
|
|
532
409
|
at: i64,
|
|
533
410
|
) -> YerbaResult {
|
|
534
411
|
let document = &mut *document;
|
|
535
|
-
let
|
|
412
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
536
413
|
let value_string = CStr::from_ptr(value).to_str().unwrap_or("");
|
|
537
414
|
|
|
538
415
|
let position = if at >= 0 {
|
|
@@ -547,7 +424,7 @@ pub unsafe extern "C" fn yerba_document_insert(
|
|
|
547
424
|
InsertPosition::Last
|
|
548
425
|
};
|
|
549
426
|
|
|
550
|
-
match document.insert_into(
|
|
427
|
+
match document.insert_into(selector_string, value_string, position) {
|
|
551
428
|
Ok(()) => YerbaResult::ok(),
|
|
552
429
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
553
430
|
}
|
|
@@ -563,60 +440,14 @@ pub unsafe extern "C" fn yerba_document_insert_object(
|
|
|
563
440
|
at: i64,
|
|
564
441
|
) -> YerbaResult {
|
|
565
442
|
let document = &mut *document;
|
|
566
|
-
let
|
|
443
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
567
444
|
let json_string = CStr::from_ptr(json).to_str().unwrap_or("");
|
|
568
445
|
|
|
569
446
|
let json_value: serde_json::Value = match serde_json::from_str(json_string) {
|
|
570
|
-
Ok(
|
|
447
|
+
Ok(value) => value,
|
|
571
448
|
Err(e) => return YerbaResult::err(&format!("Invalid JSON: {}", e)),
|
|
572
449
|
};
|
|
573
450
|
|
|
574
|
-
let try_paths = if path_string.is_empty() {
|
|
575
|
-
vec!["[]".to_string(), "[0]".to_string()]
|
|
576
|
-
} else {
|
|
577
|
-
vec![format!("{}[]", path_string), format!("{}[0]", path_string)]
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
let mut quote_style = QuoteStyle::Plain;
|
|
581
|
-
|
|
582
|
-
'outer: for try_path in &try_paths {
|
|
583
|
-
for scalar in document.get_all_typed(try_path) {
|
|
584
|
-
if scalar.kind == SyntaxKind::DOUBLE_QUOTED_SCALAR {
|
|
585
|
-
quote_style = QuoteStyle::Double;
|
|
586
|
-
break 'outer;
|
|
587
|
-
} else if scalar.kind == SyntaxKind::SINGLE_QUOTED_SCALAR {
|
|
588
|
-
quote_style = QuoteStyle::Single;
|
|
589
|
-
break 'outer;
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
if quote_style == QuoteStyle::Plain {
|
|
595
|
-
if let Some(serde_yaml::Value::Sequence(seq)) = document.get_value(path_string).as_ref() {
|
|
596
|
-
if let Some(serde_yaml::Value::Mapping(map)) = seq.first() {
|
|
597
|
-
if let Some((serde_yaml::Value::String(key_name), _)) = map.iter().next() {
|
|
598
|
-
let deep_path = if path_string.is_empty() {
|
|
599
|
-
format!("[].{}", key_name)
|
|
600
|
-
} else {
|
|
601
|
-
format!("{}[].{}", path_string, key_name)
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
for scalar in document.get_all_typed(&deep_path) {
|
|
605
|
-
if scalar.kind == SyntaxKind::DOUBLE_QUOTED_SCALAR {
|
|
606
|
-
quote_style = QuoteStyle::Double;
|
|
607
|
-
break;
|
|
608
|
-
} else if scalar.kind == SyntaxKind::SINGLE_QUOTED_SCALAR {
|
|
609
|
-
quote_style = QuoteStyle::Single;
|
|
610
|
-
break;
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
let yaml_text = crate::yaml_writer::json_to_yaml_text(&json_value, "e_style, 0);
|
|
619
|
-
|
|
620
451
|
let position = if at >= 0 {
|
|
621
452
|
InsertPosition::At(at as usize)
|
|
622
453
|
} else if !before.is_null() {
|
|
@@ -629,7 +460,7 @@ pub unsafe extern "C" fn yerba_document_insert_object(
|
|
|
629
460
|
InsertPosition::Last
|
|
630
461
|
};
|
|
631
462
|
|
|
632
|
-
match document.
|
|
463
|
+
match document.insert_object(selector_string, &json_value, position) {
|
|
633
464
|
Ok(()) => YerbaResult::ok(),
|
|
634
465
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
635
466
|
}
|
|
@@ -638,51 +469,50 @@ pub unsafe extern "C" fn yerba_document_insert_object(
|
|
|
638
469
|
#[no_mangle]
|
|
639
470
|
pub unsafe extern "C" fn yerba_document_delete(document: *mut Document, path: *const c_char) -> YerbaResult {
|
|
640
471
|
let document = &mut *document;
|
|
641
|
-
let
|
|
472
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
642
473
|
|
|
643
|
-
match document.delete(
|
|
474
|
+
match document.delete(selector_string) {
|
|
644
475
|
Ok(()) => YerbaResult::ok(),
|
|
645
476
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
646
477
|
}
|
|
647
478
|
}
|
|
648
479
|
|
|
649
480
|
#[no_mangle]
|
|
650
|
-
pub unsafe extern "C" fn yerba_document_remove(
|
|
651
|
-
document: *mut Document,
|
|
652
|
-
path: *const c_char,
|
|
653
|
-
value: *const c_char,
|
|
654
|
-
) -> YerbaResult {
|
|
481
|
+
pub unsafe extern "C" fn yerba_document_remove(document: *mut Document, path: *const c_char, value: *const c_char) -> YerbaResult {
|
|
655
482
|
let document = &mut *document;
|
|
656
|
-
let
|
|
483
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
657
484
|
let value_string = CStr::from_ptr(value).to_str().unwrap_or("");
|
|
658
485
|
|
|
659
|
-
match document.remove(
|
|
486
|
+
match document.remove(selector_string, value_string) {
|
|
660
487
|
Ok(()) => YerbaResult::ok(),
|
|
661
488
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
662
489
|
}
|
|
663
490
|
}
|
|
664
491
|
|
|
665
492
|
#[no_mangle]
|
|
666
|
-
pub unsafe extern "C" fn yerba_document_remove_at(
|
|
667
|
-
document: *mut Document,
|
|
668
|
-
path: *const c_char,
|
|
669
|
-
index: usize,
|
|
670
|
-
) -> YerbaResult {
|
|
493
|
+
pub unsafe extern "C" fn yerba_document_remove_at(document: *mut Document, path: *const c_char, index: usize) -> YerbaResult {
|
|
671
494
|
let document = &mut *document;
|
|
672
|
-
let
|
|
495
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
673
496
|
|
|
674
|
-
match document.remove_at(
|
|
497
|
+
match document.remove_at(selector_string, index) {
|
|
675
498
|
Ok(()) => YerbaResult::ok(),
|
|
676
499
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
677
500
|
}
|
|
678
501
|
}
|
|
679
502
|
|
|
680
503
|
#[no_mangle]
|
|
681
|
-
pub unsafe extern "C" fn
|
|
682
|
-
document
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
504
|
+
pub unsafe extern "C" fn yerba_document_move_item(document: *mut Document, path: *const c_char, from: usize, to: usize) -> YerbaResult {
|
|
505
|
+
let document = &mut *document;
|
|
506
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
507
|
+
|
|
508
|
+
match document.move_item(selector_string, from, to) {
|
|
509
|
+
Ok(()) => YerbaResult::ok(),
|
|
510
|
+
Err(e) => YerbaResult::err(&e.to_string()),
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
#[no_mangle]
|
|
515
|
+
pub unsafe extern "C" fn yerba_document_rename(document: *mut Document, source: *const c_char, dest: *const c_char) -> YerbaResult {
|
|
686
516
|
let document = &mut *document;
|
|
687
517
|
let source_string = CStr::from_ptr(source).to_str().unwrap_or("");
|
|
688
518
|
let dest_string = CStr::from_ptr(dest).to_str().unwrap_or("");
|
|
@@ -694,59 +524,46 @@ pub unsafe extern "C" fn yerba_document_rename(
|
|
|
694
524
|
}
|
|
695
525
|
|
|
696
526
|
#[no_mangle]
|
|
697
|
-
pub unsafe extern "C" fn yerba_document_sort(
|
|
698
|
-
document: *mut Document,
|
|
699
|
-
path: *const c_char,
|
|
700
|
-
by: *const c_char,
|
|
701
|
-
case_sensitive: bool,
|
|
702
|
-
) -> YerbaResult {
|
|
527
|
+
pub unsafe extern "C" fn yerba_document_sort(document: *mut Document, path: *const c_char, by: *const c_char, case_sensitive: bool) -> YerbaResult {
|
|
703
528
|
let document = &mut *document;
|
|
704
|
-
let
|
|
529
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
705
530
|
|
|
706
|
-
let by_string = if by.is_null() {
|
|
707
|
-
None
|
|
708
|
-
} else {
|
|
709
|
-
CStr::from_ptr(by).to_str().ok()
|
|
710
|
-
};
|
|
531
|
+
let by_string = if by.is_null() { None } else { CStr::from_ptr(by).to_str().ok() };
|
|
711
532
|
|
|
712
533
|
let sort_fields: Vec<crate::SortField> = match by_string {
|
|
713
|
-
Some(fields) => fields
|
|
714
|
-
.split(',')
|
|
715
|
-
.map(|field| {
|
|
716
|
-
if let Some(name) = field.strip_suffix(":desc") {
|
|
717
|
-
crate::SortField {
|
|
718
|
-
path: name.to_string(),
|
|
719
|
-
ascending: false,
|
|
720
|
-
}
|
|
721
|
-
} else {
|
|
722
|
-
crate::SortField {
|
|
723
|
-
path: field.to_string(),
|
|
724
|
-
ascending: true,
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
|
-
})
|
|
728
|
-
.collect(),
|
|
534
|
+
Some(fields) => crate::SortField::parse_list(fields),
|
|
729
535
|
None => vec![],
|
|
730
536
|
};
|
|
731
537
|
|
|
732
|
-
match document.sort_items(
|
|
538
|
+
match document.sort_items(selector_string, &sort_fields, case_sensitive) {
|
|
733
539
|
Ok(()) => YerbaResult::ok(),
|
|
734
540
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
735
541
|
}
|
|
736
542
|
}
|
|
737
543
|
|
|
738
544
|
#[no_mangle]
|
|
739
|
-
pub unsafe extern "C" fn
|
|
740
|
-
document: *mut Document,
|
|
741
|
-
path: *const c_char,
|
|
742
|
-
order: *const c_char,
|
|
743
|
-
) -> YerbaResult {
|
|
545
|
+
pub unsafe extern "C" fn yerba_document_reorder(document: *mut Document, path: *const c_char, by: *const c_char, order_csv: *const c_char) -> YerbaResult {
|
|
744
546
|
let document = &mut *document;
|
|
745
|
-
let
|
|
547
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
548
|
+
let by_string = CStr::from_ptr(by).to_str().unwrap_or("");
|
|
549
|
+
let order_string = CStr::from_ptr(order_csv).to_str().unwrap_or("");
|
|
550
|
+
|
|
551
|
+
let desired_order: Vec<&str> = order_string.split(',').map(|s| s.trim()).collect();
|
|
552
|
+
|
|
553
|
+
match document.reorder_items(selector_string, by_string, &desired_order) {
|
|
554
|
+
Ok(()) => YerbaResult::ok(),
|
|
555
|
+
Err(e) => YerbaResult::err(&e.to_string()),
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
#[no_mangle]
|
|
560
|
+
pub unsafe extern "C" fn yerba_document_sort_keys(document: *mut Document, path: *const c_char, order: *const c_char) -> YerbaResult {
|
|
561
|
+
let document = &mut *document;
|
|
562
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
746
563
|
let order_string = CStr::from_ptr(order).to_str().unwrap_or("");
|
|
747
564
|
let key_order: Vec<&str> = order_string.split(',').collect();
|
|
748
565
|
|
|
749
|
-
match document.sort_keys(
|
|
566
|
+
match document.sort_keys(selector_string, &key_order) {
|
|
750
567
|
Ok(()) => YerbaResult::ok(),
|
|
751
568
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
752
569
|
}
|
|
@@ -761,55 +578,32 @@ pub unsafe extern "C" fn yerba_document_quote_style(
|
|
|
761
578
|
) -> YerbaResult {
|
|
762
579
|
let document = &mut *document;
|
|
763
580
|
|
|
764
|
-
let
|
|
765
|
-
None
|
|
766
|
-
} else {
|
|
767
|
-
CStr::from_ptr(path).to_str().ok()
|
|
768
|
-
};
|
|
581
|
+
let selector = if path.is_null() { None } else { CStr::from_ptr(path).to_str().ok() };
|
|
769
582
|
|
|
770
|
-
let
|
|
583
|
+
let key = if key_style.is_null() {
|
|
771
584
|
None
|
|
772
585
|
} else {
|
|
773
|
-
CStr::from_ptr(key_style)
|
|
774
|
-
.to_str()
|
|
775
|
-
.ok()
|
|
776
|
-
.and_then(|s| s.parse::<QuoteStyle>().ok())
|
|
586
|
+
CStr::from_ptr(key_style).to_str().ok().and_then(|s| s.parse::<crate::KeyStyle>().ok())
|
|
777
587
|
};
|
|
778
588
|
|
|
779
|
-
let
|
|
589
|
+
let value = if value_style.is_null() {
|
|
780
590
|
None
|
|
781
591
|
} else {
|
|
782
|
-
CStr::from_ptr(value_style)
|
|
783
|
-
.to_str()
|
|
784
|
-
.ok()
|
|
785
|
-
.and_then(|s| s.parse::<QuoteStyle>().ok())
|
|
592
|
+
CStr::from_ptr(value_style).to_str().ok().and_then(|s| s.parse::<QuoteStyle>().ok())
|
|
786
593
|
};
|
|
787
594
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
if let Some(ref value_style) = value_quote_style {
|
|
795
|
-
if let Err(e) = document.enforce_quotes_at(value_style, path_string) {
|
|
796
|
-
return YerbaResult::err(&e.to_string());
|
|
797
|
-
}
|
|
595
|
+
match document.enforce_quote_style(key.as_ref(), value.as_ref(), selector) {
|
|
596
|
+
Ok(()) => YerbaResult::ok(),
|
|
597
|
+
Err(e) => YerbaResult::err(&e.to_string()),
|
|
798
598
|
}
|
|
799
|
-
|
|
800
|
-
YerbaResult::ok()
|
|
801
599
|
}
|
|
802
600
|
|
|
803
601
|
#[no_mangle]
|
|
804
|
-
pub unsafe extern "C" fn yerba_document_blank_lines(
|
|
805
|
-
document: *mut Document,
|
|
806
|
-
path: *const c_char,
|
|
807
|
-
count: usize,
|
|
808
|
-
) -> YerbaResult {
|
|
602
|
+
pub unsafe extern "C" fn yerba_document_blank_lines(document: *mut Document, path: *const c_char, count: usize) -> YerbaResult {
|
|
809
603
|
let document = &mut *document;
|
|
810
|
-
let
|
|
604
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
811
605
|
|
|
812
|
-
match document.enforce_blank_lines(
|
|
606
|
+
match document.enforce_blank_lines(selector_string, count) {
|
|
813
607
|
Ok(()) => YerbaResult::ok(),
|
|
814
608
|
Err(e) => YerbaResult::err(&e.to_string()),
|
|
815
609
|
}
|
|
@@ -855,42 +649,12 @@ pub unsafe extern "C" fn yerba_get_result_free(result: YerbaGetResult) {
|
|
|
855
649
|
#[no_mangle]
|
|
856
650
|
pub unsafe extern "C" fn yerba_glob_get(glob_pattern: *const c_char, path: *const c_char) -> YerbaTypedList {
|
|
857
651
|
let pattern = CStr::from_ptr(glob_pattern).to_str().unwrap_or("");
|
|
858
|
-
let
|
|
859
|
-
let
|
|
860
|
-
|
|
861
|
-
let files = match glob::glob(pattern) {
|
|
862
|
-
Ok(paths) => paths.filter_map(|p| p.ok()).collect::<Vec<_>>(),
|
|
863
|
-
Err(_) => {
|
|
864
|
-
return YerbaTypedList {
|
|
865
|
-
json: CString::new("[]").unwrap_or_default().into_raw(),
|
|
866
|
-
length: 0,
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
};
|
|
870
|
-
|
|
871
|
-
use rayon::prelude::*;
|
|
872
|
-
|
|
873
|
-
let results: Vec<serde_json::Value> = files
|
|
874
|
-
.par_iter()
|
|
875
|
-
.flat_map(|file| {
|
|
876
|
-
let mut file_results = Vec::new();
|
|
652
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
653
|
+
let scalars = crate::glob_get(pattern, selector_string);
|
|
877
654
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
let value_type = detect_yaml_type(&scalar);
|
|
882
|
-
|
|
883
|
-
file_results.push(serde_json::json!({"text": scalar.text, "type": value_type as u8}));
|
|
884
|
-
}
|
|
885
|
-
} else if let Some(scalar) = document.get_typed(path_string) {
|
|
886
|
-
let value_type = detect_yaml_type(&scalar);
|
|
887
|
-
|
|
888
|
-
file_results.push(serde_json::json!({"text": scalar.text, "type": value_type as u8}));
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
file_results
|
|
893
|
-
})
|
|
655
|
+
let results: Vec<serde_json::Value> = scalars
|
|
656
|
+
.iter()
|
|
657
|
+
.map(|scalar| serde_json::json!({"text": scalar.text, "type": detect_yaml_type(scalar) as u8}))
|
|
894
658
|
.collect();
|
|
895
659
|
|
|
896
660
|
let length = results.len();
|
|
@@ -903,89 +667,13 @@ pub unsafe extern "C" fn yerba_glob_get(glob_pattern: *const c_char, path: *cons
|
|
|
903
667
|
}
|
|
904
668
|
|
|
905
669
|
#[no_mangle]
|
|
906
|
-
pub unsafe extern "C" fn yerba_glob_find(
|
|
907
|
-
glob_pattern: *const c_char,
|
|
908
|
-
path: *const c_char,
|
|
909
|
-
condition: *const c_char,
|
|
910
|
-
select: *const c_char,
|
|
911
|
-
) -> YerbaTypedList {
|
|
670
|
+
pub unsafe extern "C" fn yerba_glob_find(glob_pattern: *const c_char, path: *const c_char, condition: *const c_char, select: *const c_char) -> YerbaTypedList {
|
|
912
671
|
let pattern = CStr::from_ptr(glob_pattern).to_str().unwrap_or("");
|
|
913
|
-
let
|
|
914
|
-
|
|
915
|
-
let
|
|
916
|
-
None
|
|
917
|
-
} else {
|
|
918
|
-
CStr::from_ptr(condition).to_str().ok()
|
|
919
|
-
};
|
|
920
|
-
|
|
921
|
-
let _select_string = if select.is_null() {
|
|
922
|
-
None
|
|
923
|
-
} else {
|
|
924
|
-
CStr::from_ptr(select).to_str().ok()
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
let files = match glob::glob(pattern) {
|
|
928
|
-
Ok(paths) => paths.filter_map(|p| p.ok()).collect::<Vec<_>>(),
|
|
929
|
-
Err(_) => {
|
|
930
|
-
return YerbaTypedList {
|
|
931
|
-
json: CString::new("[]").unwrap_or_default().into_raw(),
|
|
932
|
-
length: 0,
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
};
|
|
936
|
-
|
|
937
|
-
use rayon::prelude::*;
|
|
938
|
-
|
|
939
|
-
let select_fields: Option<Vec<&str>> = _select_string.map(|s| s.split(',').collect());
|
|
940
|
-
|
|
941
|
-
let all_results: Vec<serde_json::Value> = files
|
|
942
|
-
.par_iter()
|
|
943
|
-
.flat_map(|file| {
|
|
944
|
-
let mut file_results = Vec::new();
|
|
945
|
-
|
|
946
|
-
if let Ok(document) = Document::parse_file(file) {
|
|
947
|
-
let values = match condition_string {
|
|
948
|
-
Some(cond) => document.filter(path_string, cond),
|
|
949
|
-
None => document.get_values(path_string),
|
|
950
|
-
};
|
|
951
|
-
|
|
952
|
-
let file_string = file.to_string_lossy().to_string();
|
|
953
|
-
|
|
954
|
-
for value in &values {
|
|
955
|
-
let mut result = serde_json::Map::new();
|
|
956
|
-
result.insert("__file".to_string(), serde_json::Value::String(file_string.clone()));
|
|
957
|
-
|
|
958
|
-
match &select_fields {
|
|
959
|
-
Some(fields) => {
|
|
960
|
-
for field in fields {
|
|
961
|
-
let json_value = crate::json::resolve_select_field(value, field);
|
|
962
|
-
let json_key = crate::json::select_field_key(field);
|
|
963
|
-
result.insert(json_key, json_value);
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
None => {
|
|
968
|
-
if let serde_yaml::Value::Mapping(map) = value {
|
|
969
|
-
for (key, yaml_value) in map {
|
|
970
|
-
let json_key = match key {
|
|
971
|
-
serde_yaml::Value::String(string) => string.clone(),
|
|
972
|
-
_ => format!("{:?}", key),
|
|
973
|
-
};
|
|
974
|
-
|
|
975
|
-
result.insert(json_key, crate::json::yaml_to_json(yaml_value));
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
file_results.push(serde_json::Value::Object(result));
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
file_results
|
|
986
|
-
})
|
|
987
|
-
.collect();
|
|
672
|
+
let selector_string = CStr::from_ptr(path).to_str().unwrap_or("");
|
|
673
|
+
let condition_string = if condition.is_null() { None } else { CStr::from_ptr(condition).to_str().ok() };
|
|
674
|
+
let select_string = if select.is_null() { None } else { CStr::from_ptr(select).to_str().ok() };
|
|
988
675
|
|
|
676
|
+
let all_results = crate::glob_find(pattern, selector_string, condition_string, select_string);
|
|
989
677
|
let length = all_results.len();
|
|
990
678
|
let json = serde_json::to_string_pretty(&all_results).unwrap_or_else(|_| "[]".to_string());
|
|
991
679
|
|