use crate::types::cid::Cid;
use crate::types::nsid::Nsid;
use crate::types::string::{Datetime, Did, Handle, Rkey};
use crate::xrpc::{MessageEncoding, SubscriptionResp, XrpcSubscription};
use crate::{CowStr, Data, IntoStatic, RawData};
use alloc::vec::Vec;
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "std", derive(bon::Builder))]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "std", builder(start_fn = new))]
pub struct JetstreamParams<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
#[builder(into)]
pub wanted_collections: Option<Vec<Nsid<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
#[builder(into)]
pub wanted_dids: Option<Vec<Did<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_message_size_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub compress: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub require_hello: Option<bool>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum CommitOperation {
Create,
Update,
Delete,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RawJetstreamCommit<'a> {
#[serde(borrow)]
pub rev: CowStr<'a>,
pub operation: CommitOperation,
#[serde(borrow)]
pub collection: CowStr<'a>,
#[serde(borrow)]
pub rkey: CowStr<'a>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub record: Option<RawData<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub cid: Option<CowStr<'a>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct JetstreamCommit<'a> {
#[serde(borrow)]
pub rev: CowStr<'a>,
pub operation: CommitOperation,
#[serde(borrow)]
pub collection: Nsid<'a>,
#[serde(borrow)]
pub rkey: Rkey<'a>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub record: Option<Data<'a>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub cid: Option<Cid<'a>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct JetstreamIdentity<'a> {
#[serde(borrow)]
pub did: Did<'a>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub handle: Option<Handle<'a>>,
pub seq: i64,
pub time: Datetime,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct JetstreamAccount<'a> {
pub active: bool,
#[serde(borrow)]
pub did: Did<'a>,
pub seq: i64,
pub time: Datetime,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
pub status: Option<CowStr<'a>>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind")]
#[serde(rename_all = "lowercase")]
pub enum JetstreamMessage<'a> {
Commit {
#[serde(borrow)]
did: Did<'a>,
time_us: i64,
#[serde(borrow)]
commit: JetstreamCommit<'a>,
},
Identity {
#[serde(borrow)]
did: Did<'a>,
time_us: i64,
#[serde(borrow)]
identity: JetstreamIdentity<'a>,
},
Account {
#[serde(borrow)]
did: Did<'a>,
time_us: i64,
#[serde(borrow)]
account: JetstreamAccount<'a>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind")]
#[serde(rename_all = "lowercase")]
pub enum RawJetstreamMessage<'a> {
Commit {
#[serde(borrow)]
did: Did<'a>,
time_us: i64,
#[serde(borrow)]
commit: RawJetstreamCommit<'a>,
},
Identity {
#[serde(borrow)]
did: Did<'a>,
time_us: i64,
#[serde(borrow)]
identity: JetstreamIdentity<'a>,
},
Account {
#[serde(borrow)]
did: Did<'a>,
time_us: i64,
#[serde(borrow)]
account: JetstreamAccount<'a>,
},
#[serde(untagged)]
Unknown(RawData<'a>),
}
impl IntoStatic for CommitOperation {
type Output = CommitOperation;
fn into_static(self) -> Self::Output {
self
}
}
impl IntoStatic for JetstreamCommit<'_> {
type Output = JetstreamCommit<'static>;
fn into_static(self) -> Self::Output {
JetstreamCommit {
rev: self.rev.into_static(),
operation: self.operation,
collection: self.collection.into_static(),
rkey: self.rkey.into_static(),
record: self.record.map(|r| r.into_static()),
cid: self.cid.map(|c| c.into_static()),
}
}
}
impl IntoStatic for RawJetstreamCommit<'_> {
type Output = RawJetstreamCommit<'static>;
fn into_static(self) -> Self::Output {
RawJetstreamCommit {
rev: self.rev.into_static(),
operation: self.operation,
collection: self.collection.into_static(),
rkey: self.rkey.into_static(),
record: self.record.map(|r| r.into_static()),
cid: self.cid.map(|c| c.into_static()),
}
}
}
impl IntoStatic for JetstreamIdentity<'_> {
type Output = JetstreamIdentity<'static>;
fn into_static(self) -> Self::Output {
JetstreamIdentity {
did: self.did.into_static(),
handle: self.handle.map(|h| h.into_static()),
seq: self.seq,
time: self.time,
}
}
}
impl IntoStatic for JetstreamAccount<'_> {
type Output = JetstreamAccount<'static>;
fn into_static(self) -> Self::Output {
JetstreamAccount {
active: self.active,
did: self.did.into_static(),
seq: self.seq,
time: self.time,
status: self.status.map(|s| s.into_static()),
}
}
}
impl IntoStatic for JetstreamMessage<'_> {
type Output = JetstreamMessage<'static>;
fn into_static(self) -> Self::Output {
match self {
JetstreamMessage::Commit {
did,
time_us,
commit,
} => JetstreamMessage::Commit {
did: did.into_static(),
time_us,
commit: commit.into_static(),
},
JetstreamMessage::Identity {
did,
time_us,
identity,
} => JetstreamMessage::Identity {
did: did.into_static(),
time_us,
identity: identity.into_static(),
},
JetstreamMessage::Account {
did,
time_us,
account,
} => JetstreamMessage::Account {
did: did.into_static(),
time_us,
account: account.into_static(),
},
}
}
}
impl IntoStatic for RawJetstreamMessage<'_> {
type Output = RawJetstreamMessage<'static>;
fn into_static(self) -> Self::Output {
match self {
RawJetstreamMessage::Commit {
did,
time_us,
commit,
} => RawJetstreamMessage::Commit {
did: did.into_static(),
time_us,
commit: commit.into_static(),
},
RawJetstreamMessage::Identity {
did,
time_us,
identity,
} => RawJetstreamMessage::Identity {
did: did.into_static(),
time_us,
identity: identity.into_static(),
},
RawJetstreamMessage::Account {
did,
time_us,
account,
} => RawJetstreamMessage::Account {
did: did.into_static(),
time_us,
account: account.into_static(),
},
RawJetstreamMessage::Unknown(data) => RawJetstreamMessage::Unknown(data.into_static()),
}
}
}
pub struct JetstreamStream;
impl SubscriptionResp for JetstreamStream {
const NSID: &'static str = "jetstream";
const ENCODING: MessageEncoding = MessageEncoding::Json;
type Message<'de> = JetstreamMessage<'de>;
type Error<'de> = crate::xrpc::GenericError<'de>;
}
impl<'a> XrpcSubscription for JetstreamParams<'a> {
const NSID: &'static str = "jetstream";
const ENCODING: MessageEncoding = MessageEncoding::Json;
const CUSTOM_PATH: Option<&'static str> = Some("/subscribe");
type Stream = JetstreamStream;
}
impl IntoStatic for JetstreamParams<'_> {
type Output = JetstreamParams<'static>;
fn into_static(self) -> Self::Output {
JetstreamParams {
wanted_collections: self
.wanted_collections
.map(|v| v.into_iter().map(|s| s.into_static()).collect()),
wanted_dids: self
.wanted_dids
.map(|v| v.into_iter().map(|s| s.into_static()).collect()),
cursor: self.cursor,
max_message_size_bytes: self.max_message_size_bytes,
compress: self.compress,
require_hello: self.require_hello,
}
}
}
#[cfg_attr(feature = "std", derive(bon::Builder))]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "std", builder(start_fn = new))]
pub struct RawJetstreamParams<'a> {
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
#[builder(into)]
pub wanted_collections: Option<Vec<crate::CowStr<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(borrow)]
#[builder(into)]
pub wanted_dids: Option<Vec<crate::CowStr<'a>>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cursor: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_message_size_bytes: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub compress: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub require_hello: Option<bool>,
}
pub struct JetstreamRawStream;
impl SubscriptionResp for JetstreamRawStream {
const NSID: &'static str = "jetstream";
const ENCODING: MessageEncoding = MessageEncoding::Json;
type Message<'de> = RawJetstreamMessage<'de>;
type Error<'de> = crate::xrpc::GenericError<'de>;
}
impl<'a> XrpcSubscription for RawJetstreamParams<'a> {
const NSID: &'static str = "jetstream";
const ENCODING: MessageEncoding = MessageEncoding::Json;
const CUSTOM_PATH: Option<&'static str> = Some("/subscribe");
type Stream = JetstreamRawStream;
}
impl IntoStatic for RawJetstreamParams<'_> {
type Output = RawJetstreamParams<'static>;
fn into_static(self) -> Self::Output {
RawJetstreamParams {
wanted_collections: self
.wanted_collections
.map(|v| v.into_iter().map(|s| s.into_static()).collect()),
wanted_dids: self
.wanted_dids
.map(|v| v.into_iter().map(|s| s.into_static()).collect()),
cursor: self.cursor,
max_message_size_bytes: self.max_message_size_bytes,
compress: self.compress,
require_hello: self.require_hello,
}
}
}