0

I have implemented json rpc server with rust by looking up this.

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();
}

The above server is working as expected. Here the param takes vector or map.

For request {"jsonrpc": "2.0", "method": "say_hello", "params": {"a": 2, "b": 3}, "id": 1} it prints

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

And for request {"jsonrpc": "2.0", "method": "say_hello", "params": [2,3], "id": 1} it prints

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

How do I access these parameters from this Params enum as Map or Array?

UPDATE 1

I modified my code to get params as map -

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

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

It prints

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

UPDATE 2 Modification for accessing map by key -

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()))
});

Now I am getting following error :

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>>

Ömer Erden
  • 7,680
  • 5
  • 36
  • 45
Bopsi
  • 2,090
  • 5
  • 36
  • 58

1 Answers1

1

Not sure what you mean exactly by asking "how to access", but here it is:

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(())
}

The serde_json part is not very relevant to you. It is just a way to get a Params value. After pattern matching, the m is a serde_json::map::Map and a is regular std::vec::Vec. You can manipulate them however you wish according to their API.

edwardw
  • 12,652
  • 3
  • 40
  • 51
  • By "how to access" I meant access param by index (when array) or key (when map). Please check my updates, it's giving me different error. – Bopsi Jan 02 '20 at 09:58
  • 1
    @Bopsi `map.get("a")`. Go back to the basics, reading the Rust book would help. – edwardw Jan 02 '20 at 10:05