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
use serde_json::value::RawValue;
use serde::Serialize;
/// A trait which is implemented for anything which can be turned into
/// valid RPC parameters.
pub trait IntoRpcParams {
/// Return the params. These are expected to be encoded to JSON,
/// and take the form of either an array or object of parameters.
/// Can return `None` to avoid allocation when returning no parameters.
fn into_rpc_params(self) -> RpcParams;
}
pub type RpcParams = Option<Box<RawValue>>;
/// Parameter builder to build valid "object or "named" parameters.
/// This is the equivalent of a JSON Map object `{ key: value }`.
///
/// # Examples
///
/// ```rust
///
/// use jsonrpc_client::params::ObjectParams;
///
/// let mut builder = ObjectParams::new();
/// builder.insert("param1", 1);
/// builder.insert("param2", "abc");
///
/// // Use RPC parameters...
/// ```
#[derive(Clone, Debug)]
pub struct ObjectParams {
bytes: Vec<u8>
}
impl ObjectParams {
/// Construct a new [`ObjectParams`] instance.
pub fn new() -> Self {
ObjectParams { bytes: Vec::new() }
}
/// Insert a new named parameter.
pub fn insert<P: Serialize>(&mut self, name: &str, value: P) -> Result<(), serde_json::Error> {
if self.bytes.is_empty() {
self.bytes.push(b'{');
} else {
self.bytes.push(b',');
}
serde_json::to_writer(&mut self.bytes, name)?;
self.bytes.push(b':');
serde_json::to_writer(&mut self.bytes, &value)?;
Ok(())
}
/// Build the final output.
pub fn build(mut self) -> RpcParams {
if self.bytes.is_empty() {
return None;
}
self.bytes.push(b'}');
// Safety: This is safe because JSON does not emit invalid UTF-8:
let utf8_string = unsafe { String::from_utf8_unchecked(self.bytes) };
Some(RawValue::from_string(utf8_string).expect("valid JSON expected"))
}
}
impl IntoRpcParams for ObjectParams {
fn into_rpc_params(self) -> RpcParams {
self.build()
}
}
/// Parameter builder to build valid "array" or "unnamed" JSON-RPC parameters.
/// This is the equivalent of a JSON array like `[ value0, value1, .., valueN ]`.
///
/// # Examples
///
/// ```rust
///
/// use jsonrpc_client::params::ArrayParams;
///
/// let mut builder = ArrayParams::new();
/// builder.insert("param1");
/// builder.insert(1);
///
/// // Use RPC parameters...
/// ```
#[derive(Clone, Debug)]
pub struct ArrayParams {
bytes: Vec<u8>
}
impl ArrayParams {
/// Construct a new [`ArrayParams`] instance.
pub fn new() -> Self {
ArrayParams { bytes: Vec::new() }
}
/// Insert a new parameter.
pub fn insert<P: Serialize>(&mut self, value: P) -> Result<(), serde_json::Error> {
if self.bytes.is_empty() {
self.bytes.push(b'[');
} else {
self.bytes.push(b',');
}
serde_json::to_writer(&mut self.bytes, &value)?;
Ok(())
}
/// Build the final output.
pub fn build(mut self) -> RpcParams {
if self.bytes.is_empty() {
return None;
}
self.bytes.push(b']');
// Safety: This is safe because JSON does not emit invalid UTF-8:
let utf8_string = unsafe { String::from_utf8_unchecked(self.bytes) };
Some(RawValue::from_string(utf8_string).expect("valid JSON expected"))
}
}
impl IntoRpcParams for ArrayParams {
fn into_rpc_params(self) -> RpcParams {
self.build()
}
}