use crate::{
protocols::{ProtocolParser, ProtocolPayload},
Message, OckamError, Result,
};
use ockam_core::compat::{collections::BTreeSet, string::String, vec::Vec};
use ockam_core::{Decodable, Uint};
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Message)]
pub struct InitResponse {
pub stream_name: String,
}
impl InitResponse {
#[allow(dead_code, clippy::new_ret_no_self)]
pub fn new<S: Into<String>>(s: S) -> ProtocolPayload {
ProtocolPayload::new(
"stream_create",
Self {
stream_name: s.into(),
},
)
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Message)]
pub struct PushConfirm {
pub request_id: Uint,
pub status: Status,
pub index: Uint,
}
impl PushConfirm {
#[allow(dead_code, clippy::new_ret_no_self)]
pub fn new<S: Into<Status>>(request_id: u64, status: S, index: u64) -> ProtocolPayload {
ProtocolPayload::new(
"stream_push",
Self {
request_id: request_id.into(),
index: index.into(),
status: status.into(),
},
)
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum Status {
Ok,
Error,
}
impl From<bool> for Status {
fn from(b: bool) -> Self {
if b {
Self::Ok
} else {
Self::Error
}
}
}
impl From<Option<()>> for Status {
fn from(b: Option<()>) -> Self {
b.map(|_| Self::Ok).unwrap_or(Self::Error)
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Message)]
pub struct PullResponse {
pub request_id: Uint,
pub messages: Vec<StreamMessage>,
}
impl PullResponse {
#[allow(dead_code, clippy::new_ret_no_self)]
pub fn new<T: Into<Vec<StreamMessage>>>(request_id: u64, messages: T) -> ProtocolPayload {
ProtocolPayload::new(
"stream_pull",
Self {
request_id: request_id.into(),
messages: messages.into(),
},
)
}
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Message)]
pub struct StreamMessage {
pub index: Uint,
pub data: Vec<u8>,
}
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct IndexResponse {
pub client_id: String,
pub stream_name: String,
pub index: Option<Uint>,
}
#[allow(clippy::enum_variant_names)]
#[derive(Serialize, Deserialize, Message)]
pub enum Response {
Init(InitResponse),
PushConfirm(PushConfirm),
PullResponse(PullResponse),
Index(IndexResponse),
}
impl ProtocolParser for Response {
fn check_id(id: &str) -> bool {
vec![
"stream_create",
"stream_push",
"stream_pull",
"stream_index",
]
.into_iter()
.collect::<BTreeSet<_>>()
.contains(id)
}
fn parse(ProtocolPayload { protocol, data }: ProtocolPayload) -> Result<Self> {
Ok(match protocol.as_str() {
"stream_create" => Response::Init(InitResponse::decode(&data)?),
"stream_push" => Response::PushConfirm(PushConfirm::decode(&data)?),
"stream_pull" => Response::PullResponse(PullResponse::decode(&data)?),
"stream_index" => Response::Index(IndexResponse::decode(&data)?),
_ => return Err(OckamError::NoSuchProtocol.into()),
})
}
}