#[allow(dead_code)]
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
pub const USER_AGENT_VALUE: &str = concat!("ActorClient-Rust/", env!("CARGO_PKG_VERSION"));
#[allow(dead_code)]
pub const HEADER_ACTOR_QUERY: &str = "x-rivet-query";
pub const HEADER_ENCODING: &str = "x-rivet-encoding";
pub const HEADER_CONN_PARAMS: &str = "x-rivet-conn-params";
#[allow(dead_code)]
pub const HEADER_ACTOR_ID: &str = "x-rivet-actor";
#[allow(dead_code)]
pub const HEADER_CONN_ID: &str = "x-rivet-conn";
#[allow(dead_code)]
pub const HEADER_CONN_TOKEN: &str = "x-rivet-conn-token";
pub const HEADER_RIVET_TARGET: &str = "x-rivet-target";
pub const HEADER_RIVET_ACTOR: &str = "x-rivet-actor";
pub const HEADER_RIVET_TOKEN: &str = "x-rivet-token";
pub const HEADER_RIVET_NAMESPACE: &str = "x-rivet-namespace";
pub const PATH_CONNECT_WEBSOCKET: &str = "/connect";
pub const PATH_WEBSOCKET_PREFIX: &str = "/websocket/";
pub type RawWebSocket =
tokio_tungstenite::WebSocketStream<tokio_tungstenite::MaybeTlsStream<tokio::net::TcpStream>>;
pub const WS_PROTOCOL_STANDARD: &str = "rivet";
pub const WS_PROTOCOL_TARGET: &str = "rivet_target.";
pub const WS_PROTOCOL_ACTOR: &str = "rivet_actor.";
pub const WS_PROTOCOL_ENCODING: &str = "rivet_encoding.";
pub const WS_PROTOCOL_CONN_PARAMS: &str = "rivet_conn_params.";
pub const WS_PROTOCOL_CONN_ID: &str = "rivet_conn.";
pub const WS_PROTOCOL_CONN_TOKEN: &str = "rivet_conn_token.";
pub const WS_PROTOCOL_TOKEN: &str = "rivet_token.";
#[derive(Debug, Clone, Copy)]
pub enum TransportKind {
WebSocket,
Sse,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EncodingKind {
Json,
Cbor,
Bare,
}
impl EncodingKind {
pub fn as_str(&self) -> &str {
match self {
EncodingKind::Json => "json",
EncodingKind::Cbor => "cbor",
EncodingKind::Bare => "bare",
}
}
}
impl Default for EncodingKind {
fn default() -> Self {
Self::Bare
}
}
impl ToString for EncodingKind {
fn to_string(&self) -> String {
self.as_str().to_string()
}
}
pub type ActorKey = Vec<String>;
pub fn serialize_actor_key(key: &ActorKey) -> String {
const KEY_SEPARATOR: char = '/';
const EMPTY_KEY: &str = "/";
if key.is_empty() {
return EMPTY_KEY.to_string();
}
key.iter()
.map(|part| {
if part.is_empty() {
return "\\0".to_string();
}
let mut escaped = String::with_capacity(part.len());
for ch in part.chars() {
if ch == '\\' || ch == KEY_SEPARATOR {
escaped.push('\\');
}
escaped.push(ch);
}
escaped
})
.collect::<Vec<_>>()
.join(&KEY_SEPARATOR.to_string())
}
#[cfg(test)]
mod actor_key_tests {
use super::serialize_actor_key;
#[test]
fn matches_the_ts_sdk_format() {
assert_eq!(serialize_actor_key(&vec![]), "/");
assert_eq!(serialize_actor_key(&vec!["a".into()]), "a");
assert_eq!(serialize_actor_key(&vec!["a".into(), "b".into()]), "a/b");
assert_eq!(serialize_actor_key(&vec!["".into()]), "\\0");
assert_eq!(serialize_actor_key(&vec!["a/b".into()]), "a\\/b");
assert_eq!(serialize_actor_key(&vec!["a\\b".into()]), "a\\\\b");
}
}