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
mod handler;
use std::sync::atomic::{AtomicUsize, Ordering};

use handler::*;

mod session;
use session::ServiceSession;

use serde::{Deserialize, Serialize};

use crate::{channel::TransportChannel, ErrorCode};

/// JSONRPC server context structure.
///
#[derive(Default, Clone)]
pub struct Server {
    tag: String,
    methods: HandlerClonerRegister<ServerHandler>,
    async_methods: HandlerClonerRegister<AsyncServerHandler>,
}

impl Server {
    pub fn new<S>(tag: S) -> Self
    where
        S: Into<String>,
    {
        Self {
            tag: tag.into(),
            ..Default::default()
        }
    }
    /// Register jsonrpc server sync handler
    pub fn handle<P, R, F>(self, method: &'static str, f: F) -> Self
    where
        F: FnMut(P) -> Result<Option<R>, ErrorCode> + 'static + Clone + Sync + Send,
        for<'a> P: Deserialize<'a> + Serialize,
        R: Serialize + Default,
    {
        self.methods.register_handler(method, to_handler(method, f));

        self
    }

    /// Register jsonrpc server async handler
    ///
    /// The register async handler be required to implement [`Clone`] trait.
    pub fn async_handle<P, R, F, FR>(self, method: &'static str, f: F) -> Self
    where
        F: FnMut(P) -> FR + 'static + Sync + Send + Clone,
        FR: std::future::Future<Output = Result<Option<R>, ErrorCode>> + Sync + Send + 'static,
        for<'a> P: Deserialize<'a> + Serialize + Send,
        R: Serialize + Default,
    {
        self.async_methods
            .register_handler(method, to_async_handler(method, f));

        self
    }

    pub fn accept<C: TransportChannel>(&mut self, channel: C) {
        static INSTANCE: AtomicUsize = AtomicUsize::new(1);

        let id = format!("{}_{}", self.tag, INSTANCE.fetch_add(1, Ordering::SeqCst));

        let (input, output) = channel.framed();

        let mut session = ServiceSession::<C>::new(
            id,
            input,
            output,
            self.methods.clone(),
            self.async_methods.clone(),
        );

        C::spawn(async move { session.run().await });
    }
}