JSON pointer: Difference between revisions

Line 926:
Error: /no/such/thing does not exist: 'no'
Error: bad/pointer does not exist: Non-empty JSON pointers must begin with /
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">use serde_json::{ json, Value };
 
type JSONPointer = Vec<String>;
 
fn new_json_pointer(pstring: &str) -> Vec<String> {
return jp_parse(pstring).unwrap();
}
 
fn resolve(p: JSONPointer, data: Value) -> Result<Value, String> {
return p.iter().fold(Ok(data), |accum, val| get_item(accum, val));
}
 
fn jp_parse(pst: &str) -> Result<Vec<String>, String> {
if pst == "" {
return Ok([].to_vec());
}
if pst.chars().nth(0).unwrap() != '/' {
return Err(String::from("Non-empty JSON pointers must begin with /"));
}
return Ok(
pst
.split("/")
.map(|s| String::from(s.replace("~1", "/").replace("~0", "~")))
.collect::<Vec<String>>()[1..]
.to_vec()
);
}
 
fn get_item<'a>(obj: Result<Value, String>, token: &str) -> Result<Value, String> {
match obj {
Err(_) => {
return obj; // propagate along
}
Ok(ob) => {
match ob {
Value::Array(arr) => {
let idx = usize::from_str_radix(token, 10);
match idx {
Err(..) => {
return Err(String::from("ParseIntErr"));
}
Ok(i) => {
if i < arr.len() {
return Ok(Value::String(arr[i].to_string()));
}
return Err(String::from("Index {token} out of range"));
}
}
}
Value::Object(dic) => {
if dic.contains_key(token) {
return Ok(dic[token].clone());
}
return Err(String::from("Key error with {token}"));
}
_ => {
return Err(String::from("Unknown object {obj}"));
}
}
}
}
}
 
fn main() {
let doc =
json!({
"wiki" : {
"links" : [
"https://rosettacode.org/wiki/Rosetta_Code",
"https://discord.com/channels/1011262808001880065",
],
},
"" : "Rosetta",
" " : "Code",
"g/h" : "chrestomathy",
"i~j" : "site",
"abc" : ["is", "a"],
"def" : {"" : "programming"},
});
let examples = [
"",
"/",
"/ ",
"/abc",
"/def/",
"/g~1h",
"/i~0j",
"/wiki/links/0",
"/wiki/links/1",
"/wiki/links/2",
"/wiki/name",
"/no/such/thing",
"bad/pointer",
];
for p in examples {
let pointer = new_json_pointer(p);
let result = resolve(pointer, doc.clone());
match result {
Ok(val) => println!("\"{p}\" -> \"{val}\""),
Err(err) => println!("Error: {p} does not exist: {err}"),
}
}
}
</syntaxhighlight>{{out}}
<pre>
"" -> "{"":"Rosetta"," ":"Code","abc":["is","a"],"def":{"":"programming"},"g/h":"chrestomathy","i~j":"site","wiki":{"links":["https://rosettacode.org/wiki/Rosetta_Code","https://discord.com/channels/1011262808001880065"]}}"
"/" -> ""Rosetta""
"/ " -> ""Code""
"/abc" -> "["is","a"]"
"/def/" -> ""programming""
"/g~1h" -> ""chrestomathy""
"/i~0j" -> ""site""
"/wiki/links/0" -> ""\"https://rosettacode.org/wiki/Rosetta_Code\"""
"/wiki/links/1" -> ""\"https://discord.com/channels/1011262808001880065\"""
Error: /wiki/links/2 does not exist: Index {token} out of range
Error: /wiki/name does not exist: Key error with {token}
Error: /no/such/thing does not exist: Key error with {token}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "Non-empty JSON pointers must begin with /"', src\main.rs:6:30
</pre>
 
4,108

edits