Hi team.
Having some great fun testing on sim2h guys. Fantastic job, very nice for a newb like me!
Battling with rust though and looking for some help on the best/right way to deserialize some output from the DHT from a websocket call by my RUST program.
My setup has two agents bob and alice. Bob is able to read alices chain and gets the following standard output from the dht:
Text(
"{\"jsonrpc\":\"2.0\",
\"result\":\"{
\\\"Ok\\\":[{
\\\"price\\\":\\\"62.4563\\\",
\\\"author_id\\\":\\\"HcSciaDXrXkqxwv7gukMChvazIuscvcrk457t8n88cmo95en4sPCEdDKvj4ucja\\\"
},
{
\\\"price\\\":\\\"62.4563\\\",
\\\"author_id\\\":\\\"HcSciaDXrXkqxwv7gukMChvazIuscvcrk457t8n88cmo95en4sPCEdDKvj4ucja\\\"
}
]}\",
\"id\":\"bob
\"}",
I want to organize this output so have created the following structures:
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
struct Root {
jsonrpc: String,
result: Result,
id: String,
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
struct Result {
#[serde(rename = "Ok")]
ok: Vec<Ok>,
}
#[derive(Default, Debug, Clone, PartialEq, serde_derive::Serialize, serde_derive::Deserialize)]
struct Ok {
price: String,
author_id: String,
}
I want my program to capture in a variable only the last āprice:ā string published on alices chain but Iām struggling to work out the syntax to even just println! the price variable let alone find and capture the last one in the dynamic object.
Can someone help with a clean way to do that?
What have I tried:
Iāve tried to call even the first āpriceā variable above using the following which compiles but panics on the last println! when I run it:
let res = get_from_dht("HcSciaDXrXkqxwv7gukMChvazIuscvcrk457t8n88cmo95en4sPCEdDKvj4ucja".to_string());
println!("{:#?}", res); //i see all of alices entries.. success
let dhtjson: Root = serde_json::from_str(&res).unwrap();
println!("{:#?}", dhtjson.result.ok[0].price);
It gives me the following error:
"{\"jsonrpc\":\"2.0\",\"result\":\"{\\\"Ok\\\":[{\\\"price\\\":\\\"Norm\\\",\\\"author_id\\\":\\\"HcSciaDXrXkqxwv7gukMChvazIuscvcrk457t8n88cmo95en4sPCEdDKvj4ucja\\\"}]}\",\"id\":\"bob\"}"
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"{\\\"Ok\\\":[{\\\"price\\\":\\\"Norm\\\",\\\"author_id\\\":\\\"HcSciaDXrXkqxwv7gukMChvazIuscvcrk457t8n88cmo95en4sPCEdDKvj4ucja\\\"}]}\", expected struct Result", line: 1, column: 141)', src/libcore/result.rs:1084:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
here also is my dht call which works:
fn get_from_dht(_address: String) -> String {
let json = serde_json::json!(
{"id": "bob",
"jsonrpc": "2.0",
"method": "call",
"params": {"instance_id": "test-instance",
"zome": "spot_signal",
"function": "get_price",
"args": {"agent_address": _address}}
});
let (tx, rx) = channel();
let tx1 = &tx;
connect("ws://localhost:3402", |out| {
// call an RPC method with parameters
out.send(json.to_string()).unwrap();
move |msg| {
println!("Got message: {:#?}", msg);
tx1.send(msg).ok();
out.close(CloseCode::Normal)
}
}).unwrap();
rx.recv().unwrap().to_string() // get the value in the dht via websocket
}
Can you suggest a syntax and approach above to take the return and extract only a particular variable from the multilayered result (i.e. in this case the last price entry included on alices chain)?