use super::*;
#[derive(Debug, Clone)]
pub(in crate::rpc_processor) enum RPCOperationKind {
Question(Box<RPCQuestion>),
Statement(Box<RPCStatement>),
Answer(Box<RPCAnswer>),
}
impl RPCOperationKind {
pub fn desc(&self) -> &'static str {
match self {
RPCOperationKind::Question(q) => q.desc(),
RPCOperationKind::Statement(s) => s.desc(),
RPCOperationKind::Answer(a) => a.desc(),
}
}
pub async fn validate(
&self,
validate_context: &RPCValidateContext<'_>,
) -> Result<(), RPCError> {
match self {
RPCOperationKind::Question(r) => r.validate(validate_context).await,
RPCOperationKind::Statement(r) => r.validate(validate_context),
RPCOperationKind::Answer(r) => r.validate(validate_context).await,
}
}
pub fn decode(
decode_context: &RPCDecodeContext,
kind_reader: &veilid_capnp::operation::kind::Reader,
) -> Result<Self, RPCError> {
let which_reader = kind_reader.which()?;
let out = match which_reader {
veilid_capnp::operation::kind::Which::Question(r) => {
let q_reader = r?;
let out = RPCQuestion::decode(decode_context, &q_reader)?;
RPCOperationKind::Question(Box::new(out))
}
veilid_capnp::operation::kind::Which::Statement(r) => {
let q_reader = r?;
let out = RPCStatement::decode(decode_context, &q_reader)?;
RPCOperationKind::Statement(Box::new(out))
}
veilid_capnp::operation::kind::Which::Answer(r) => {
let q_reader = r?;
let out = RPCAnswer::decode(decode_context, &q_reader)?;
RPCOperationKind::Answer(Box::new(out))
}
};
Ok(out)
}
pub fn encode(
&self,
builder: &mut veilid_capnp::operation::kind::Builder,
) -> Result<(), RPCError> {
match self {
RPCOperationKind::Question(k) => k.encode(&mut builder.reborrow().init_question()),
RPCOperationKind::Statement(k) => k.encode(&mut builder.reborrow().init_statement()),
RPCOperationKind::Answer(k) => k.encode(&mut builder.reborrow().init_answer()),
}
}
}
#[derive(Debug, Clone)]
pub(in crate::rpc_processor) struct RPCOperation {
op_id: OperationId,
sender_peer_info: SenderPeerInfo,
kind: RPCOperationKind,
}
impl RPCOperation {
pub fn new_question(question: RPCQuestion, sender_peer_info: SenderPeerInfo) -> Self {
Self {
op_id: OperationId::new(get_random_u64()),
sender_peer_info,
kind: RPCOperationKind::Question(Box::new(question)),
}
}
pub fn new_statement(statement: RPCStatement, sender_peer_info: SenderPeerInfo) -> Self {
Self {
op_id: OperationId::new(get_random_u64()),
sender_peer_info,
kind: RPCOperationKind::Statement(Box::new(statement)),
}
}
pub fn new_answer(
op_id: OperationId,
answer: RPCAnswer,
sender_peer_info: SenderPeerInfo,
) -> Self {
Self {
op_id,
sender_peer_info,
kind: RPCOperationKind::Answer(Box::new(answer)),
}
}
pub async fn validate(
&self,
validate_context: &RPCValidateContext<'_>,
) -> Result<(), RPCError> {
self.kind.validate(validate_context).await
}
pub fn op_id(&self) -> OperationId {
self.op_id
}
pub fn sender_peer_info(&self) -> SenderPeerInfo {
self.sender_peer_info.clone()
}
pub fn kind(&self) -> &RPCOperationKind {
&self.kind
}
pub fn destructure(self) -> (OperationId, SenderPeerInfo, RPCOperationKind) {
(self.op_id, self.sender_peer_info, self.kind)
}
pub fn decode(
decode_context: &RPCDecodeContext,
operation_reader: &veilid_capnp::operation::Reader,
) -> Result<Self, RPCError> {
let op_id = OperationId::new(operation_reader.get_op_id());
let opt_peer_info = if operation_reader.has_sender_peer_info() {
let pi_reader = operation_reader.get_sender_peer_info()?;
let pi = Arc::new(decode_peer_info(decode_context, &pi_reader)?);
Some(pi)
} else {
None
};
let target_node_info_ts = Timestamp::new(operation_reader.get_target_node_info_ts());
let kind_reader = operation_reader.get_kind();
let kind = RPCOperationKind::decode(decode_context, &kind_reader)?;
Ok(RPCOperation {
op_id,
sender_peer_info: opt_peer_info
.map(|pi| SenderPeerInfo::new(pi, target_node_info_ts))
.unwrap_or(SenderPeerInfo::new_no_peer_info(target_node_info_ts)),
kind,
})
}
pub fn encode(&self, builder: &mut veilid_capnp::operation::Builder) -> Result<(), RPCError> {
builder.set_op_id(self.op_id.as_u64());
if let Some(sender_peer_info) = &self.sender_peer_info.opt_peer_info() {
let mut pi_builder = builder.reborrow().init_sender_peer_info();
encode_peer_info(sender_peer_info, &mut pi_builder)?;
}
builder.set_target_node_info_ts(self.sender_peer_info.target_node_info_ts().as_u64());
let mut k_builder = builder.reborrow().init_kind();
self.kind.encode(&mut k_builder)?;
Ok(())
}
}