mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 02:48:12 +08:00
Add useful attributes to the JSON and Regex nodes (#4069)
* Add useful attributes to the JSON and Regex nodes * Code review fix
This commit is contained in:
@@ -210,11 +210,13 @@ fn query_json(
|
||||
let mut results = Vec::new();
|
||||
resolve_all(&value, &segments, !unquote_strings, &mut results);
|
||||
|
||||
results.into_iter().next().unwrap_or_default()
|
||||
results.into_iter().next().map(|(text, _ty)| text).unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Extracts every matched value from a JSON string using a path expression (see that parameter's description for its syntax). A list of zero or more resultant strings is produced. The `[]` path accessor is used to read more than one value.
|
||||
///
|
||||
/// Each row carries a `type` attribute holding the matched value's JSON type (`"string"`, `"number"`, `"bool"`, `"null"`, `"object"`, or `"array"`).
|
||||
///
|
||||
/// This is useful in conjunction with the nodes:
|
||||
/// • **Index Elements**: access the `N`th query result.
|
||||
/// • **String to Number**: convert numeric query results to numbers.
|
||||
@@ -246,7 +248,7 @@ fn query_json_all(
|
||||
let mut results = Vec::new();
|
||||
resolve_all(&value, &segments, !unquote_strings, &mut results);
|
||||
|
||||
results.into_iter().map(TableRow::new_from_element).collect()
|
||||
results.into_iter().map(|(text, ty)| TableRow::new_from_element(text).with_attribute("type", ty.to_string())).collect()
|
||||
}
|
||||
|
||||
/// A parsed segment of a JSON access path.
|
||||
@@ -402,6 +404,18 @@ fn json_value_to_string(value: &serde_json::Value, quote_strings: bool) -> Strin
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a short JSON-type name (`"string"`, `"number"`, `"bool"`, `"null"`, `"object"`, `"array"`) for a parsed value.
|
||||
fn json_value_type_name(value: &serde_json::Value) -> &'static str {
|
||||
match value {
|
||||
serde_json::Value::String(_) => "string",
|
||||
serde_json::Value::Number(_) => "number",
|
||||
serde_json::Value::Bool(_) => "bool",
|
||||
serde_json::Value::Null => "null",
|
||||
serde_json::Value::Object(_) => "object",
|
||||
serde_json::Value::Array(_) => "array",
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigates a JSON value by one path segment, returning the resulting value (or `None` if the path is invalid).
|
||||
fn json_navigate<'a>(value: &'a serde_json::Value, segment: &JsonPathSegment) -> Option<&'a serde_json::Value> {
|
||||
match segment {
|
||||
@@ -416,7 +430,7 @@ fn json_navigate<'a>(value: &'a serde_json::Value, segment: &JsonPathSegment) ->
|
||||
}
|
||||
|
||||
/// Recursively resolves a path against a JSON value, fanning out at each `[]` and collecting leaf results.
|
||||
fn resolve_all(value: &serde_json::Value, segments: &[JsonPathSegment], quote_strings: bool, results: &mut Vec<String>) {
|
||||
fn resolve_all(value: &serde_json::Value, segments: &[JsonPathSegment], quote_strings: bool, results: &mut Vec<(String, &'static str)>) {
|
||||
// Find the next IterateAll in the remaining segments
|
||||
let Some(iterate_position) = segments.iter().position(|s| matches!(s, JsonPathSegment::IterateAll)) else {
|
||||
// No more [] segments, navigate the rest linearly
|
||||
@@ -425,7 +439,7 @@ fn resolve_all(value: &serde_json::Value, segments: &[JsonPathSegment], quote_st
|
||||
let Some(next) = json_navigate(current, segment) else { return };
|
||||
current = next;
|
||||
}
|
||||
results.push(json_value_to_string(current, quote_strings));
|
||||
results.push((json_value_to_string(current, quote_strings), json_value_type_name(current)));
|
||||
return;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user