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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! RPC messages.

use std::collections::BTreeMap;

use serde::{de::DeserializeOwned, Deserialize, Serialize};

use crate::func_ret::ReturnValue;

pub(crate) use self::internal::*;

/// Traits and their blanket implementations used internally to encode/decode RPC messages.
mod internal {
    use serde::{de::DeserializeOwned, Deserialize, Serialize};

    use crate::errors::Error;

    use super::{Args, Payload};

    /// Internal trait for the RPC request type. Implemented by `Query` and `AuthQuery`.
    pub(crate) trait Request: Sized {
        fn to_bencode(&self) -> Result<Vec<u8>, Error>;
    }

    /// Internal trait for the RPC response type. Implemented by `GenericResponse`.
    pub(crate) trait Response: Sized {
        fn from_bencode(bytes: &[u8]) -> Result<Self, Error>;
    }

    // Implements `Request` for `Query` and `QueryAuth`.
    impl<T: Serialize> Request for T {
        fn to_bencode(&self) -> Result<Vec<u8>, Error> {
            bencode::to_bytes(self).map_err(|e| Error::Protocol(e))
        }
    }

    // Implements `Response` for `GenericResponse`.
    impl<T: DeserializeOwned> Response for T {
        fn from_bencode(bytes: &[u8]) -> Result<Self, Error> {
            bencode::from_bytes(bytes).map_err(|e| Error::Protocol(e))
        }
    }

    /// Generic RPC query without authentication.
    #[derive(Serialize, Clone, PartialEq, Eq, Debug)]
    pub(crate) struct Query<A: Args> {
        #[serde(rename = "txid")]
        pub(crate) txid: String,

        #[serde(rename = "q")]
        pub(crate) q: String,

        #[serde(rename = "args")]
        pub(crate) args: A,
    }

    /// Generic RPC query with authentication.
    #[derive(Serialize, Clone, PartialEq, Eq, Debug)]
    pub(crate) struct AuthQuery<A: Args> {
        #[serde(rename = "txid")]
        pub(crate) txid: String,

        #[serde(rename = "q")]
        pub(crate) q: String,

        #[serde(rename = "aq")]
        pub(crate) aq: String,

        #[serde(rename = "args")]
        pub(crate) args: A,

        #[serde(rename = "cookie")]
        pub(crate) cookie: String,

        #[serde(rename = "hash")]
        pub(crate) hash: String,
    }

    /// Generic RPC response.
    #[derive(Deserialize, Clone, PartialEq, Eq, Debug)]
    pub(crate) struct GenericResponse<P: Payload> {
        #[serde(rename = "txid")]
        pub(crate) txid: String,

        #[serde(rename = "error", default)]
        pub(crate) error: String,

        #[serde(flatten, default)]
        #[serde(bound(deserialize = "P: DeserializeOwned"))]
        pub(crate) payload: P,
    }
}

/// Trait for RPC query arguments. Can be any serializable type.
pub trait Args: Serialize {}

/// Trait for RPC query return value. Can be any deserializable type with `Default`.
pub trait Payload: DeserializeOwned + Default {}

// Blanket `Args` impl for any serializable type.
impl<T: Serialize> Args for T {}

// Blanket `Payload` impl for any deserializable type with `Default`.
impl<T: DeserializeOwned + Default> Payload for T {}

/// Empty payload or arguments.
#[derive(Deserialize, Serialize, Default, Clone, PartialEq, Eq, Debug)]
pub struct Empty {}

/// Generic return value with fields exposed as a map.
pub type GenericResponsePayload = BTreeMap<String, ReturnValue>;

/// Return value for `cookie` remote function.
#[derive(Deserialize, Default, Clone, PartialEq, Eq, Debug)]
pub(crate) struct CookieResponsePayload {
    #[serde(rename = "cookie")]
    pub(crate) cookie: String,
}

/// Arguments for `Admin_availableFunctions` remote function.
#[derive(Serialize, Clone, PartialEq, Eq, Debug)]
pub(crate) struct AvailableFnsQueryArg {
    #[serde(rename = "page")]
    pub(crate) page: usize,
}

/// Return value for `Admin_availableFunctions` remote function.
#[derive(Deserialize, Default, Clone, PartialEq, Eq, Debug)]
pub(crate) struct AvailableFnsResponsePayload {
    #[serde(rename = "availableFunctions", default)]
    pub(crate) available_fns: RemoteFnDescrs,
}

/// Map of remote function names to map of arguments.
pub(crate) type RemoteFnDescrs = BTreeMap<String, RemoteFnArgsDescr>;

/// Map of function argument names to argument descriptions.
pub(crate) type RemoteFnArgsDescr = BTreeMap<String, RemoteFnArgDescr>;

/// Remote function argument description.
#[derive(Deserialize, Default, Clone, PartialEq, Eq, Debug)]
pub(crate) struct RemoteFnArgDescr {
    #[serde(rename = "required")]
    pub(crate) required: u8,

    #[serde(rename = "type")]
    pub(crate) typ: String,
}