web5_rust/dwn/
json_rpc.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
use super::Error;

use super::structs::{DwnResponse, Packet};
use super::traits::{Server, Client};
use crate::dids::Did;

use super::Dwn;

use std::collections::BTreeMap;

use jsonrpc_v2::{Data, Params, Server as JsonServer};
use tokio::sync::Mutex;
use uuid::Uuid;
use url::Url;

#[jsonrpc_client::api]
trait Method {
    async fn process_packet(&self, recipient: Did, payload: Vec<u8>) -> BTreeMap<Uuid, DwnResponse>;
    async fn debug(&self) -> String;
}

#[jsonrpc_client::implement(Method)]
#[derive(Debug)]
struct JsonClient {
    inner: reqwest::Client,
    base_url: Url,
}

#[derive(Debug, Clone)]
pub struct JsonRpcClient {}

impl JsonRpcClient {
    pub async fn client_debug(url: &str) -> String {
        let client = JsonClient{inner: reqwest::Client::new(), base_url: Url::parse(url).unwrap()};
        client.debug().await.unwrap()
    }
}

#[async_trait::async_trait]
impl Client for JsonRpcClient {
    async fn send_request(&self, body: String, url: Url) -> Result<String, Error> {
        let p = serde_json::from_str::<Packet>(&body)?;
        let client = JsonClient{inner: reqwest::Client::new(), base_url: url};
        Ok(serde_json::to_string(&client.process_packet(p.recipient, p.payload).await.map_err(|e|
            Error::json_rpc(&e.to_string())
        )?)?)
    }
}

impl jsonrpc_v2::ErrorLike for Error {}

#[derive(Debug, Clone)]
pub struct JsonRpcServer {}

impl JsonRpcServer {
    async fn process_packet(
        data: Data<Mutex<Dwn>>, Params(params): Params<Packet>
    ) -> Result<BTreeMap<Uuid, DwnResponse>, Error> {
        data.lock().await.process_packet(params).await
    }

    async fn debug(data: Data<Mutex<Dwn>>) -> Result<String, Error> {
        data.lock().await.debug().await
    }
}

#[async_trait::async_trait]
impl Server for JsonRpcServer {
    async fn start_server(
        &self, dwn: Dwn, port: u32
    ) -> Result<actix_web::dev::Server, Error> {
        let rpc = JsonServer::new()
            .with_data(Data::new(Mutex::new(dwn)))
            .with_method("process_packet", Self::process_packet)
            .with_method("debug", Self::debug)
            .finish();
        let server = actix_web::HttpServer::new(move || {
            actix_web::App::new().service(
                actix_web::web::service("/")
                    .guard(actix_web::guard::Post())
                    .finish(rpc.clone().into_web_service()),
            )
        });
        Ok(server.bind(&format!("0.0.0.0:{}", port))?.run())
    }
}