Skip to content

Instantly share code, notes, and snippets.

@euclio
Last active September 24, 2016 15:00
Show Gist options
  • Save euclio/af20a74d73ca316bf184c1f6c9212223 to your computer and use it in GitHub Desktop.
Save euclio/af20a74d73ca316bf184c1f6c9212223 to your computer and use it in GitHub Desktop.
use std::io;
use erased_serde;
use serde::{self, Error, Serialize, Deserialize};
const REQUEST_TYPE: u32 = 0;
const NOTIFICATION_TYPE: u32 = 2;
/// A msgpack-RPC request.
pub enum Request {
/// An RPC request. Every request should have a response.
Request {
/// The ID of the request.
id: u32,
/// The RPC method to be called.
method: String,
/// The parameters of the RPC method.
params: Vec<Box<erased_serde::Serialize + Send>>,
},
/// An RPC notification. Notifications do not expect responses.
Notification {
/// The RPC method to be called.
method: String,
/// The parameters of the RPC method.
params: Vec<Box<erased_serde::Serialize + Send>>,
},
}
impl Request {
/// Creates a new `Request` containing a msgpack-RPC request.
///
/// The caller must supply a unique ID for the request.
pub fn request<M>(id: u32,
method: M,
params: Vec<Box<erased_serde::Serialize + Send>>)
-> Request
where M: Into<String>
{
Request::Request {
id: id,
method: method.into(),
params: params,
}
}
/// Creates a new `Request` containing a msgpack-RPC notification.
///
/// Notifications do not expect to receive responses.
pub fn notification<M>(method: M, params: Vec<Box<erased_serde::Serialize + Send>>) -> Request
where M: Into<String>
{
Request::Notification {
method: method.into(),
params: params,
}
}
/// Returns the ID of the request.
///
/// If the request is a `Notification`, the request does not have an ID.
pub fn id(&self) -> Option<u32> {
match *self {
Request::Request { id, .. } => Some(id),
Request::Notification { .. } => None,
}
}
/// Returns the method of the request.
pub fn method(&self) -> &str {
match *self {
Request::Request { ref method, .. } => &method,
Request::Notification { ref method, .. } => &method,
}
}
}
impl serde::Serialize for Request {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
where S: serde::Serializer
{
match *self {
Request::Request { id, ref method, ref params } => {
let request = (REQUEST_TYPE, id, method, *params);
request.serialize(serializer)
}
Request::Notification { ref method, ref params } => {
let notification = (NOTIFICATION_TYPE, method, *params);
notification.serialize(serializer)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment