1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
//! Advanced Ockam worker protocols
//!
//! This module primarily contains types and parsing utilities used in
//! different high-level Ockam utility protocols
use crate::{Message, Result};
use ockam_core::{compat::vec::Vec, ProtocolId};
use serde::{Deserialize, Serialize};
pub mod channel;
pub mod pipe;
pub mod stream;
/// A protocol payload wrapper for pre-parsing.
#[derive(Debug, Serialize, Deserialize, Message)]
pub struct ProtocolPayload {
/// The type of protocol, which specifies how `data` is encoded.
pub protocol: ProtocolId,
/// The payload, encoded in a way determined by `protocol`.
pub data: Vec<u8>,
}
impl ProtocolPayload {
/// Take an encodable message type and wrap it into a protocol payload.
///
/// ## Decoding payloads
///
/// In order to easily decode incoming `ProtocolPayload`s, it is
/// recommended to use the `ProtocolParser` abstraction, which handles
/// matching between different decoders based on the protocol ID.
pub fn new<P: Into<ProtocolId>, S: Message>(p: P, d: S) -> Self {
Self {
protocol: p.into(),
data: d.encode().expect("Failed to serialise protocol payload"),
}
}
}
/// Map a `ProtocolPayload` to a protocol specific type.
///
/// This trait should be implemented for the facade enum-type of a
/// protocol, meaning that the usage will look something like this.
///
/// ```no_compile
/// async fn handle_message(&mut self, _: &mut Context, msg: Routed<Any>) -> Result<()> {
/// let protocol_payload = ProtocolPayload::decode(msg.payload())?;
/// let resp = MyProtocolResponse::parse(protocol_payload)?;
/// println!("{:?}", resp);
/// Ok(())
/// }
/// ```
pub trait ProtocolParser: Sized {
/// A function which checks whether this parser should be called
/// for a particular protocol payload.
///
/// Internally it's recommended to use static strings and a set
/// operation to speed up repeated queries.
fn check_id(id: &str) -> bool;
/// Parse a [ProtocolPayload], which must have a [type](ProtocolId)
/// supported by this parser.
fn parse(pp: ProtocolPayload) -> Result<Self>;
}