use rmpv::Value;
#[non_exhaustive]
struct MessageType;
impl MessageType {
pub const REQUEST: u64 = 0;
pub const RESPONSE: u64 = 1;
pub const NOTIFICATION: u64 = 2;
}
#[derive(Debug, PartialEq)]
pub enum Message {
Request {
id: u64,
method: String,
params: Value,
},
Response {
id: u64,
error: Value,
result: Value,
},
Notification {
method: String,
params: Value,
},
}
impl<'de> serde::Deserialize<'de> for Message {
fn deserialize<D>(d: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = Value::deserialize(d)?;
match value.as_array() {
Some(arr) => match arr[0].as_u64().unwrap() {
MessageType::REQUEST => Ok(Self::Request {
id: arr[1].as_u64().unwrap(),
method: arr[2].as_str().unwrap().to_string(),
params: arr[3].to_owned(),
}),
MessageType::RESPONSE => Ok(Self::Response {
id: arr[1].as_u64().unwrap(),
error: arr[2].to_owned(),
result: arr[3].to_owned(),
}),
MessageType::NOTIFICATION => Ok(Self::Notification {
method: arr[1].as_str().unwrap().to_string(),
params: arr[2].to_owned(),
}),
msg_type => Err(serde::de::Error::custom(format!(
"Invalid message type: {}",
msg_type
))),
},
None => Err(serde::de::Error::custom("Value is not array")),
}
}
}
impl serde::Serialize for Message {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match self {
Message::Request { id, method, params } => Value::from(vec![
Value::from(MessageType::REQUEST),
Value::from(*id),
Value::from(method.to_owned()),
Value::from(params.to_owned()),
]),
Message::Response { id, error, result } => Value::from(vec![
Value::from(MessageType::RESPONSE),
Value::from(id.to_owned()),
error.to_owned(),
result.to_owned(),
]),
Message::Notification { method, params } => Value::from(vec![
Value::from(MessageType::NOTIFICATION),
Value::from(method.to_owned()),
Value::from(params.to_owned()),
]),
}
.serialize(serializer)
}
}