use serde_json::Value; use serde_json::Value::*; use std::string::String; use regex::Regex; fn main() { let data = r#"{ "id": "chatcmpl-9KmDSgvDNpdWzZMjNikOFzWyZRi8D", "object": "chat.completion", "created": 1714738930, "model": "gpt-4-turbo-2024-04-09", "choices": [ { "index": 0, "message": { "role": "assistant", "content": null, "tool_calls": [ { "id": "call_lPmkbGFiJkvuXvzs09uUYdzD", "type": "function", "function": { "name": "${FUNC}", "arguments": "${ARGS}" } } ] }, "logprobs": null, "finish_reason": "tool_calls" } ], "usage": { "prompt_tokens": 80, "completion_tokens": 23, "total_tokens": 103 }, "system_fingerprint": "fp_3450ce39d5" }"#; let data2 = r#"{ "id": "chatcmpl-9KmDSgvDNpdWzZMjNikOFzWyZRi8D", "object": "chat.completion", "created": 1714738930, "model": "gpt-4-turbo-2024-04-09", "choices": [ { "index": 0, "message": { "role": "assistant", "content": null, "tool_calls": [ { "id": "call_lPmkbGFiJkvuXvzs09uUYdzD", "type": "function", "function": { "name": "calc", "arguments": "{\"expr\":\"(60 * 24) * 265.25\"}" } } ] }, "logprobs": null, "finish_reason": "tool_calls" } ], "usage": { "prompt_tokens": 80, "completion_tokens": 23, "total_tokens": 103 }, "system_fingerprint": "fp_3450ce39d5" }"#; //"arguments": "{\"expr\":\"(60 * 24) * 265.25\"}" // Convert to a string of JSON and print it out let v: serde_json::Value = serde_json::from_str(data).unwrap(); let found = finder(&v, String::new(), &mut vec![]); println!("{found:?}"); let f: serde_json::Value = serde_json::from_str(data2).unwrap(); getter(&f, &found[0], &mut vec![]); } fn getter(val: &Value, places: &str, found: &mut Vec) -> Vec { //println!("=== {places}"); let mut v = val; //for vars in places { let items: Vec<&str> = places.split(':').collect(); let var = *items.last().unwrap(); for (pos, i) in items.iter().enumerate() { //println!("### {i}"); if *i == var { if let Value::String(it) = v { println!("{it}"); } } else { if let Value::Array(it) = v { for ai in it { getter(ai, &items[pos..].join(":"), found); } } else if let Value::Object(ob) = v { v = &v[i]; //println!("{i} -> {ob:?}"); //println!("-- {i} {v}"); //cur = ob.get().unwrap(); /* for (_oi, ov) in ob { //getter(ov, &items[pos+1..].join(":"), found); println!("{ov}"); } */ } else { v = &v[i]; } }; } //} found.clone() } fn finder(v: &Value, res: String, found: &mut Vec) -> Vec { match v { Null => { }, Bool(_b) => { }, Number(_n) => { }, String(s) => { let re = Regex::new(r#"\$\{[A-Z0-9_]+\}"#).unwrap(); if re.is_match(s) { let f = format!("{res}{s}"); if !found.contains(&f) { found.push(f); } } }, Array(a) => { for v in a { finder(v, res.clone(), found); } }, Object(o) => { for (k, v) in o.iter() { finder(v, res.clone() + k + ":", found); } }, }; found.clone() }