diff --git a/node-graph/nodes/gcore/src/logic.rs b/node-graph/nodes/gcore/src/logic.rs index 0b21b5d956..1f245b799a 100644 --- a/node-graph/nodes/gcore/src/logic.rs +++ b/node-graph/nodes/gcore/src/logic.rs @@ -90,6 +90,47 @@ fn string_split( string.split(&delimeter).map(str::to_string).collect() } +/// Gets a value from either a json object or array given as a string input. +/// For example, for the input {"name": "ferris"} the key "name" will return "ferris". +#[node_macro::node(category("Text"))] +fn json_get( + _: impl Ctx, + /// The json data. + data: String, + /// The key to index the object with. + key: String, +) -> String { + use serde_json::Value; + let Ok(value): Result = serde_json::from_str(&data) else { + return "Input is not valid json".into(); + }; + match value { + Value::Array(ref arr) => { + let Ok(index): Result = key.parse() else { + log::error!("Json input is an array, but key is not a number"); + return String::new(); + }; + let Some(value) = arr.get(index) else { + log::error!("Index {} out of bounds for len {}", index, arr.len()); + return String::new(); + }; + value.to_string() + } + Value::Object(map) => { + let Some(value) = map.get(&key) else { + log::error!("Key {key} not found in object"); + return String::new(); + }; + match value { + Value::String(s) => s.clone(), + Value::Number(n) => n.to_string(), + complex => complex.to_string(), + } + } + _ => String::new(), + } +} + /// Evaluates either the "If True" or "If False" input branch based on whether the input condition is true or false. #[node_macro::node(category("Math: Logic"))] async fn switch(