use serde::{Deserialize, Serialize};
use crate::{BearerToken, StreamId, TokenId, TokenPermissions};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Visibility {
#[default]
Private,
Public,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct CreateStreamRequest {
#[serde(default)]
pub visibility: Visibility,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expires_in_secs: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub issue_tokens: Option<Vec<TokenPermissions>>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IssuedStreamToken {
pub token_id: TokenId,
pub permissions: TokenPermissions,
#[serde(serialize_with = "crate::ids::serialize_bearer_token")]
pub token: BearerToken,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CreateStreamResponse {
pub stream_id: StreamId,
pub visibility: Visibility,
pub expires_at: String,
pub tokens: Vec<IssuedStreamToken>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct IssueTokenRequest {
pub permissions: TokenPermissions,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expires_at: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IssueTokenResponse {
pub token_id: TokenId,
pub permissions: TokenPermissions,
#[serde(serialize_with = "crate::ids::serialize_bearer_token")]
pub token: BearerToken,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct RevokeTokenRequest {
pub token_id: TokenId,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum StreamTokenStatus {
Active,
Expired,
Revoked,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct StreamTokenSummary {
pub token_id: TokenId,
pub permissions: TokenPermissions,
pub status: StreamTokenStatus,
pub issued_at: String,
pub expires_at: Option<String>,
pub revoked_at: Option<String>,
pub is_current: bool,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct ListTokensResponse {
pub tokens: Vec<StreamTokenSummary>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct StreamInfoResponse {
pub stream_id: StreamId,
pub basin: String,
pub visibility: Visibility,
pub state: String,
pub expires_at: String,
pub active_token_count: usize,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct UpdateStreamRequest {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub visibility: Option<Visibility>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expires_at: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct StreamTailResponse {
pub stream_id: StreamId,
pub next_s2_seq_num: u64,
pub last_timestamp_ms: Option<u64>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct StreamRangeResponse {
pub stream_id: StreamId,
pub first_s2_seq_num: Option<u64>,
pub first_timestamp_ms: Option<u64>,
pub next_s2_seq_num: u64,
pub last_timestamp_ms: Option<u64>,
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]
fn omits_absent_create_stream_options() {
let request = CreateStreamRequest::default();
assert_eq!(
serde_json::to_value(request).expect("serialize create request"),
json!({ "visibility": "private" })
);
}
#[test]
fn serializes_requested_stream_lifetime() {
let request = CreateStreamRequest {
expires_in_secs: Some(604_800),
..CreateStreamRequest::default()
};
let value = serde_json::to_value(request).expect("serialize create request");
assert_eq!(value["expires_in_secs"], json!(604_800));
assert_eq!(
serde_json::from_value::<CreateStreamRequest>(value)
.expect("deserialize create request")
.expires_in_secs,
Some(604_800)
);
}
#[test]
fn serializes_token_mutations_and_omits_absent_stream_update() {
let token = IssueTokenRequest {
permissions: TokenPermissions::read(),
expires_at: None,
};
let token_id: TokenId = "0123456789abcdefghjkmnpq".parse().expect("token id");
assert_eq!(
serde_json::to_value(token).expect("serialize token request"),
json!({ "permissions": "r" })
);
assert_eq!(
serde_json::to_value(RevokeTokenRequest { token_id })
.expect("serialize token revocation request"),
json!({ "token_id": "0123456789abcdefghjkmnpq" })
);
assert_eq!(
serde_json::to_value(UpdateStreamRequest::default()).expect("serialize update request"),
json!({})
);
}
}