Rust jsonrpc-core 以映射或数组的形式访问参数

Rust jsonrpc-core accessing Params as map or array

我通过查找 this 实现了 json 带有 Rust 的 rpc 服务器。

use jsonrpc_core::*;
use jsonrpc_http_server::*;

fn main() {
    let mut io = IoHandler::new();
    io.add_method("say_hello", |_: Params| {
        println!("Params : {:?}", params);
        Ok(Value::String("hello".to_string()))
    });

    let _server = ServerBuilder::new(io)
        .start_http(&"127.0.0.1:3030".parse().unwrap())
        .expect("Unable to start RPC server");

    _server.wait();
}

以上服务器运行正常。这里的参数采用矢量或地图。

对于请求 {"jsonrpc": "2.0", "method": "say_hello", "params": {"a": 2, "b": 3}, "id": 1} 它打印

Params : Map({"a": Number(2), "b": Number(3)})

并且对于请求 {"jsonrpc": "2.0", "method": "say_hello", "params": [2,3], "id": 1} 它打印

Params : Array([Number(42), Number(23)])

如何从这个 Params 枚举中以映射或数组的形式访问这些参数?

更新 1

我修改了我的代码以获取参数作为地图 -

io.add_method("say_hello", |params: Params| {
    let map: HashMap<String, Value> = params.parse().unwrap();
    println!("Params : {:?}", map);

    Ok(Value::String("hello".to_string()))
});

它打印

Params : {"a": Number(2), "b": Number(3)}

更新 2 按键访问地图的修改 -

io.add_method("say_hello", |params: Params| {
    let map: HashMap<String, Value> = params.parse().unwrap();
    println!("Params : {:?}", map);

    let var_a = map.get(&"a");
    let var_b = map.get(&"b");

    println!("A : {:?}, B: {:?}", var_a, var_b);
    Ok(Value::String("hello".to_string()))
});

现在我收到以下错误:

error[E0277]: the trait bound `std::string::String:
std::borrow::Borrow<&str>` is not satisfied   --> src/main.rs:41:29   
   | 
41 |             let var_a = map.get(&"a");    
   |                             ^^^ the trait `std::borrow::Borrow<&str>` is not implemented for `std::string::String`    
   |
    = help: the following implementations were found:
        <std::string::String as std::borrow::Borrow<str>>

不确定你问 "how to access" 的确切意思,但这里是:

use jsonrpc_core::types::params::Params;  // jsonrpc-core = "14.0.5"
use serde_json;  // serde_json = "1.0.44"

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let map = r#"{"a": 2, "b": 3}"#;
    let param = serde_json::from_str::<Params>(map)?;
    if let Params::Map(m) = param {
        println!("Total {} elements: ", m.len());
        for k in m.keys() {
            println!("\t{} => {:?}", k, m.get(k));
        }
    }

    let arr = r#"[2,3]"#;
    let param = serde_json::from_str::<Params>(arr)?;
    if let Params::Array(a) = param {
        println!("Totle {} elements: {:?}", a.len(), a);
    }

    Ok(())
}

serde_json 部分与您关系不大。这只是获取 Params 值的一种方式。模式匹配后,m 是一个serde_json::map::Map and a is regular std::vec::Vec。您可以根据 API.

随心所欲地操纵它们