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
use crate::Error;

pub use self::value::Value;

pub mod value;

mod message_channel;
mod method_channel;
mod standard_codec;

pub use message_channel::*;
pub use method_channel::*;
pub use standard_codec::*;

pub struct MethodCall<V> {
    pub method: String,
    pub args: V,
}

type MethodCallResult<V> = Result<V, MethodCallError<V>>;

#[derive(Debug, Clone)]
pub struct MethodCallError<V> {
    pub code: String,
    pub message: Option<String>,
    pub details: V,
}

impl<V> MethodCallError<V> {
    pub fn from_code_message(code: &str, message: &str) -> Self
    where
        V: Default,
    {
        Self {
            code: code.into(),
            message: Some(message.into()),
            details: Default::default(),
        }
    }
}

impl<V> From<Error> for MethodCallError<V>
where
    V: Default,
{
    fn from(e: Error) -> Self {
        Self {
            code: format!("{:?}", e),
            message: Some(format!("{}", e)),
            details: Default::default(),
        }
    }
}

pub trait MessageCodec<V>: Send + Sync {
    /// Methods for plain messages
    fn encode_message(&self, v: &V) -> Vec<u8>;
    fn decode_message(&self, buf: &[u8]) -> Option<V>;
}

pub trait MethodCodec<V>: Send + Sync {
    fn decode_method_call(&self, buf: &[u8]) -> Option<MethodCall<V>>;
    fn encode_success_envelope(&self, v: &V) -> Vec<u8>;
    fn encode_error_envelope(&self, code: &str, message: Option<&str>, details: &V) -> Vec<u8>;

    fn encode_method_call_result(&self, response: &MethodCallResult<V>) -> Vec<u8> {
        match response {
            MethodCallResult::Ok(data) => self.encode_success_envelope(data),
            MethodCallResult::Err(err) => {
                self.encode_error_envelope(&err.code, err.message.as_deref(), &err.details)
            }
        }
    }

    /// Methods for calling into dart
    fn encode_method_call(&self, v: &MethodCall<V>) -> Vec<u8>;
    fn decode_envelope(&self, buf: &[u8]) -> Option<MethodCallResult<V>>;
}