2024-05-19 22:19:43 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use serde_json::{Map, Value};
|
|
|
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
|
|
|
|
|
|
|
pub type Payload = Map<String, Value>;
|
|
|
|
|
2024-05-20 21:01:05 +00:00
|
|
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
2024-05-19 22:19:43 +00:00
|
|
|
pub struct Message {
|
2024-05-20 00:08:47 +00:00
|
|
|
pub src: String,
|
|
|
|
pub dest: String,
|
|
|
|
pub body: Body,
|
2024-05-19 22:19:43 +00:00
|
|
|
}
|
|
|
|
|
2024-05-20 00:08:47 +00:00
|
|
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
2024-05-19 22:19:43 +00:00
|
|
|
pub struct Body {
|
|
|
|
#[serde(rename = "type")]
|
|
|
|
pub typ: String,
|
|
|
|
#[serde(default, skip_serializing_if = "u64_zero_by_ref")]
|
|
|
|
pub msg_id: u64,
|
|
|
|
#[serde(default, skip_serializing_if = "u64_zero_by_ref")]
|
|
|
|
pub in_reply_to: u64,
|
|
|
|
#[serde(flatten)]
|
|
|
|
pub payload: Payload,
|
|
|
|
}
|
|
|
|
|
2024-05-20 00:08:47 +00:00
|
|
|
impl Body {
|
|
|
|
pub fn from_type(typ: &str) -> Self {
|
|
|
|
Body {
|
|
|
|
typ: typ.to_string(),
|
|
|
|
..Default::default()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_msg_id(self, msg_id: u64) -> Self {
|
|
|
|
let mut b = self;
|
|
|
|
b.msg_id = msg_id;
|
|
|
|
b
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_in_reply_to(self, in_reply_to: u64) -> Self {
|
|
|
|
let mut b = self;
|
|
|
|
b.in_reply_to = in_reply_to;
|
|
|
|
b
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn with_payload(self, payload: Payload) -> Self {
|
|
|
|
let mut b = self;
|
|
|
|
b.payload = payload;
|
|
|
|
b
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn init_ok(msg_id: u64, in_reply_to: u64) -> Body {
|
|
|
|
Body::from_type("init_ok")
|
|
|
|
.with_msg_id(msg_id)
|
|
|
|
.with_in_reply_to(in_reply_to)
|
|
|
|
}
|
|
|
|
|
2024-05-19 22:19:43 +00:00
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
|
|
#[serde(untagged)]
|
|
|
|
pub enum ErrorCode {
|
|
|
|
Definite(DefiniteError),
|
|
|
|
Indefinite(IndefiniteError),
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize_repr, Deserialize_repr)]
|
|
|
|
#[repr(u64)]
|
|
|
|
pub enum DefiniteError {
|
|
|
|
NodeNotFound = 2,
|
|
|
|
NotSupported = 10,
|
|
|
|
TemporarilyUnavailable = 11,
|
|
|
|
MalformedRequest = 12,
|
|
|
|
Abort = 14,
|
|
|
|
KeyNotFound = 20,
|
|
|
|
KeyAlreadyExists = 21,
|
|
|
|
PreconditionFailed = 22,
|
|
|
|
TxnConflict = 30,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Serialize_repr, Deserialize_repr)]
|
|
|
|
#[repr(u64)]
|
|
|
|
pub enum IndefiniteError {
|
|
|
|
Timeout = 0,
|
|
|
|
Crash = 13,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn error(msg_id: u64, in_reply_to: u64, code: ErrorCode, text: Option<&str>) -> Body {
|
|
|
|
Body {
|
|
|
|
typ: "error".to_string(),
|
|
|
|
msg_id,
|
|
|
|
in_reply_to,
|
|
|
|
payload: [
|
|
|
|
("code".to_string(), serde_json::to_value(code).unwrap()),
|
|
|
|
("text".to_string(), serde_json::to_value(text).unwrap()),
|
|
|
|
]
|
|
|
|
.into_iter()
|
|
|
|
.collect(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(clippy::trivially_copy_pass_by_ref)]
|
|
|
|
fn u64_zero_by_ref(num: &u64) -> bool {
|
|
|
|
*num == 0
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn error_codes() {
|
|
|
|
let ec = ErrorCode::Definite(DefiniteError::Abort);
|
|
|
|
let e = serde_json::to_string(&ec).unwrap();
|
|
|
|
assert_eq!(&e, "14");
|
|
|
|
}
|
|
|
|
}
|