use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::collections::BTreeMap;
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct SendRequest {
pub source: String,
pub destination: String,
pub payload: JsonValue,
#[serde(default)]
pub delivery_method: Option<String>,
#[serde(default)]
pub stamp_cost: Option<u32>,
#[serde(default)]
pub include_ticket: Option<bool>,
#[serde(default)]
pub try_propagation_on_fail: Option<bool>,
pub idempotency_key: Option<String>,
pub ttl_ms: Option<u64>,
pub correlation_id: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
impl SendRequest {
pub fn new(
source: impl Into<String>,
destination: impl Into<String>,
payload: JsonValue,
) -> Self {
Self {
source: source.into(),
destination: destination.into(),
payload,
delivery_method: None,
stamp_cost: None,
include_ticket: None,
try_propagation_on_fail: None,
idempotency_key: None,
ttl_ms: None,
correlation_id: None,
extensions: BTreeMap::new(),
}
}
pub fn with_idempotency_key(mut self, key: impl Into<String>) -> Self {
self.idempotency_key = Some(key.into());
self
}
pub fn with_ttl_ms(mut self, ttl_ms: u64) -> Self {
self.ttl_ms = Some(ttl_ms);
self
}
pub fn with_correlation_id(mut self, correlation_id: impl Into<String>) -> Self {
self.correlation_id = Some(correlation_id.into());
self
}
pub fn with_delivery_method(mut self, method: impl Into<String>) -> Self {
self.delivery_method = Some(method.into());
self
}
pub fn with_stamp_cost(mut self, stamp_cost: u32) -> Self {
self.stamp_cost = Some(stamp_cost);
self
}
pub fn with_include_ticket(mut self, include_ticket: bool) -> Self {
self.include_ticket = Some(include_ticket);
self
}
pub fn with_try_propagation_on_fail(mut self, try_propagation_on_fail: bool) -> Self {
self.try_propagation_on_fail = Some(try_propagation_on_fail);
self
}
pub fn with_extension(mut self, key: impl Into<String>, value: JsonValue) -> Self {
self.extensions.insert(key.into(), value);
self
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct GroupSendRequest {
pub source: String,
pub destinations: Vec<String>,
pub payload: JsonValue,
pub idempotency_key: Option<String>,
pub ttl_ms: Option<u64>,
pub correlation_id: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
impl GroupSendRequest {
pub fn new(
source: impl Into<String>,
destinations: impl IntoIterator<Item = impl Into<String>>,
payload: JsonValue,
) -> Self {
Self {
source: source.into(),
destinations: destinations.into_iter().map(Into::into).collect(),
payload,
idempotency_key: None,
ttl_ms: None,
correlation_id: None,
extensions: BTreeMap::new(),
}
}
pub fn with_idempotency_key(mut self, key: impl Into<String>) -> Self {
self.idempotency_key = Some(key.into());
self
}
pub fn with_ttl_ms(mut self, ttl_ms: u64) -> Self {
self.ttl_ms = Some(ttl_ms);
self
}
pub fn with_correlation_id(mut self, correlation_id: impl Into<String>) -> Self {
self.correlation_id = Some(correlation_id.into());
self
}
pub fn with_extension(mut self, key: impl Into<String>, value: JsonValue) -> Self {
self.extensions.insert(key.into(), value);
self
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum GroupRecipientState {
Accepted,
Deferred,
Failed,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct GroupSendOutcome {
pub destination: String,
pub state: GroupRecipientState,
pub message_id: Option<MessageId>,
pub retryable: bool,
pub reason_code: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct GroupSendResult {
pub outcomes: Vec<GroupSendOutcome>,
pub accepted_count: usize,
pub deferred_count: usize,
pub failed_count: usize,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct BatchSendRequest {
pub batch_id: String,
pub source: String,
pub messages: Vec<BatchSendItem>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct BatchSendItem {
pub id: String,
pub destination: String,
pub payload: JsonValue,
#[serde(default)]
pub delivery_method: Option<String>,
#[serde(default)]
pub stamp_cost: Option<u32>,
#[serde(default)]
pub include_ticket: Option<bool>,
#[serde(default)]
pub try_propagation_on_fail: Option<bool>,
pub idempotency_key: Option<String>,
pub ttl_ms: Option<u64>,
pub correlation_id: Option<String>,
#[serde(default)]
pub extensions: BTreeMap<String, JsonValue>,
}
impl BatchSendItem {
pub fn new(id: impl Into<String>, destination: impl Into<String>, payload: JsonValue) -> Self {
Self {
id: id.into(),
destination: destination.into(),
payload,
delivery_method: None,
stamp_cost: None,
include_ticket: None,
try_propagation_on_fail: None,
idempotency_key: None,
ttl_ms: None,
correlation_id: None,
extensions: BTreeMap::new(),
}
}
pub fn with_idempotency_key(mut self, key: impl Into<String>) -> Self {
self.idempotency_key = Some(key.into());
self
}
pub fn with_ttl_ms(mut self, ttl_ms: u64) -> Self {
self.ttl_ms = Some(ttl_ms);
self
}
pub fn with_correlation_id(mut self, correlation_id: impl Into<String>) -> Self {
self.correlation_id = Some(correlation_id.into());
self
}
pub fn with_extension(mut self, key: impl Into<String>, value: JsonValue) -> Self {
self.extensions.insert(key.into(), value);
self
}
pub fn with_delivery_method(mut self, method: impl Into<String>) -> Self {
self.delivery_method = Some(method.into());
self
}
pub fn with_stamp_cost(mut self, stamp_cost: u32) -> Self {
self.stamp_cost = Some(stamp_cost);
self
}
pub fn with_include_ticket(mut self, include_ticket: bool) -> Self {
self.include_ticket = Some(include_ticket);
self
}
pub fn with_try_propagation_on_fail(mut self, try_propagation_on_fail: bool) -> Self {
self.try_propagation_on_fail = Some(try_propagation_on_fail);
self
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct BatchSendResult {
pub batch_id: String,
pub accepted_count: usize,
pub rejected_count: usize,
pub results: Vec<BatchSendItemResult>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct BatchSendItemResult {
pub id: String,
#[serde(default)]
pub message_id: Option<String>,
pub accepted: bool,
#[serde(default)]
pub error: Option<BatchSendItemError>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct BatchSendItemError {
pub code: String,
#[serde(default)]
pub message: String,
#[serde(default)]
pub category: Option<String>,
#[serde(default)]
pub retryable: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct MessageId(pub String);
impl From<String> for MessageId {
fn from(value: String) -> Self {
Self(value)
}
}
impl From<&str> for MessageId {
fn from(value: &str) -> Self {
Self(value.to_owned())
}
}
impl Display for MessageId {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.0.as_str())
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum DeliveryState {
Queued,
Dispatching,
InFlight,
Sent,
Delivered,
Failed,
Cancelled,
Expired,
Rejected,
#[serde(other)]
Unknown,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[non_exhaustive]
pub struct DeliverySnapshot {
pub message_id: MessageId,
pub state: DeliveryState,
pub terminal: bool,
pub last_updated_ms: u64,
pub attempts: u32,
pub reason_code: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[non_exhaustive]
pub struct Ack {
pub accepted: bool,
pub revision: Option<u64>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
#[non_exhaustive]
pub enum CancelResult {
Accepted,
AlreadyTerminal,
NotFound,
TooLateToCancel,
Unsupported,
}