use serde::{Deserialize, Serialize};
use crate::endpoint::Endpoint;
use crate::transport::{FormatPreference, TransportPreference};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SubscriptionDescriptor {
pub feed: String,
#[serde(default)]
pub columns: Option<Vec<String>>,
#[serde(default = "FilterExpr::empty")]
pub filter: FilterExpr,
#[serde(default)]
pub sampling: Option<Sampling>,
#[serde(default)]
pub transport_pref: TransportPreference,
#[serde(default)]
pub format_pref: Option<FormatPreference>,
}
impl SubscriptionDescriptor {
pub fn new(feed: impl Into<String>) -> Self {
Self {
feed: feed.into(),
columns: None,
filter: FilterExpr::empty(),
sampling: None,
transport_pref: TransportPreference::any(),
format_pref: None,
}
}
pub fn columns<I, S>(mut self, cols: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
self.columns = Some(cols.into_iter().map(Into::into).collect());
self
}
pub fn transport_pref(mut self, pref: TransportPreference) -> Self {
self.transport_pref = pref;
self
}
pub fn format(mut self, fmt: FormatPreference) -> Self {
self.format_pref = Some(fmt);
self
}
pub fn sampling(mut self, sampling: Sampling) -> Self {
self.sampling = Some(sampling);
self
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Sampling {
pub stride: u32,
}
impl Sampling {
pub fn every(stride: u32) -> Self {
Self { stride: stride.max(1) }
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
#[non_exhaustive]
pub enum FilterExpr {
Empty,
}
impl FilterExpr {
pub fn empty() -> Self {
Self::Empty
}
pub fn is_empty(&self) -> bool {
matches!(self, Self::Empty)
}
}
impl Default for FilterExpr {
fn default() -> Self {
Self::Empty
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "outcome", rename_all = "snake_case")]
#[non_exhaustive]
pub enum SubscribeResponse {
Ack(SubscribeAck),
Err(SubscribeError),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SubscribeAck {
pub endpoint: Endpoint,
pub format: FormatPreference,
#[serde(default)]
pub negotiated_columns: Option<Vec<String>>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SubscribeError {
pub code: SubscribeErrorCode,
pub message: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum SubscribeErrorCode {
UnknownFeed,
UnsupportedTransport,
UnsupportedFormat,
UnsupportedCapability,
Internal,
}