tailsurf 0.3.0

Rust SDK for tail.surf live transcript streams
Documentation
//! Identifiers and secret bearer-token values used by the TSF API.

use rand::Rng;
use secrecy::ExposeSecret;
use serde::{Serialize, Serializer};

/// Stable 160-bit identifier for a stream.
pub type StreamId = ubid::Ubid160;

/// Stable 120-bit identifier for an issued stream token.
pub type TokenId = ubid::Ubid120;

/// Secret account or stream bearer token.
pub type BearerToken = secrecy::SecretString;

/// Stable 128-bit identity assigned by a writer and reused across reconnects.
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub struct WriterId([u8; 16]);

impl WriterId {
    /// Encoded writer ID length.
    pub const BYTE_LEN: usize = 16;

    /// Generates a cryptographically random writer ID.
    pub fn new_random() -> Self {
        let mut bytes = [0_u8; Self::BYTE_LEN];
        fill_random(&mut bytes);
        Self(bytes)
    }

    /// Creates a writer ID from its exact binary representation.
    pub const fn from_bytes(bytes: [u8; Self::BYTE_LEN]) -> Self {
        Self(bytes)
    }

    /// Returns the exact binary representation.
    pub const fn as_bytes(&self) -> &[u8; Self::BYTE_LEN] {
        &self.0
    }
}

fn fill_random(bytes: &mut [u8]) {
    rand::rng().fill_bytes(bytes);
}

impl Serialize for WriterId {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_bytes(self.as_bytes())
    }
}

pub(crate) fn serialize_bearer_token<S>(
    token: &BearerToken,
    serializer: S,
) -> Result<S::Ok, S::Error>
where
    S: Serializer,
{
    serializer.serialize_str(token.expose_secret())
}