use crate::primitives::RawJson;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MsgKind {
Request,
Response,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Message {
pub msg_kind: MsgKind,
pub frames: Vec<Frame>,
}
pub mod frame_type {
pub const END: u8 = 0x00;
pub const REQ_HEADER: u8 = 0x01;
pub const PUSH_COMMIT: u8 = 0x02;
pub const PULL_HEADER: u8 = 0x03;
pub const SUBSCRIPTION: u8 = 0x04;
pub const RESP_HEADER: u8 = 0x10;
pub const PUSH_RESULT: u8 = 0x11;
pub const SUB_START: u8 = 0x12;
pub const COMMIT: u8 = 0x13;
pub const SEGMENT_REF: u8 = 0x14;
pub const SEGMENT_INLINE: u8 = 0x15;
pub const SUB_END: u8 = 0x16;
pub const LEASE: u8 = 0x19;
pub const ERROR: u8 = 0x1F;
pub const REQUEST_TYPES: &[u8] = &[REQ_HEADER, PUSH_COMMIT, PULL_HEADER, SUBSCRIPTION];
pub const RESPONSE_TYPES: &[u8] = &[
RESP_HEADER,
PUSH_RESULT,
SUB_START,
COMMIT,
SEGMENT_REF,
SEGMENT_INLINE,
SUB_END,
LEASE,
ERROR,
];
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Op {
Upsert,
Delete,
}
impl Op {
pub fn name(self) -> &'static str {
match self {
Op::Upsert => "upsert",
Op::Delete => "delete",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SubStatus {
Active,
Revoked,
Reset,
}
impl SubStatus {
pub fn name(self) -> &'static str {
match self {
SubStatus::Active => "active",
SubStatus::Revoked => "revoked",
SubStatus::Reset => "reset",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PushStatus {
Applied,
Cached,
Rejected,
}
impl PushStatus {
pub fn name(self) -> &'static str {
match self {
PushStatus::Applied => "applied",
PushStatus::Cached => "cached",
PushStatus::Rejected => "rejected",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MediaType {
Rows,
Sqlite,
}
impl MediaType {
pub fn name(self) -> &'static str {
match self {
MediaType::Rows => "rows",
MediaType::Sqlite => "sqlite",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Operation {
pub table: String,
pub row_id: String,
pub op: Op,
pub base_version: Option<i64>,
pub payload: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Change {
pub table_index: u16,
pub row_id: String,
pub op: Op,
pub row_version: Option<i64>,
pub scopes: Vec<(String, String)>,
pub row: Option<Vec<u8>>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum OpResult {
Applied {
op_index: i32,
},
Conflict {
op_index: i32,
code: String,
message: String,
server_version: i64,
server_row: Vec<u8>,
},
Error {
op_index: i32,
code: String,
message: String,
retryable: bool,
},
}
#[derive(Debug, Clone, PartialEq)]
pub enum Frame {
ReqHeader {
client_id: String,
schema_version: i32,
},
PushCommit {
client_commit_id: String,
operations: Vec<Operation>,
},
PullHeader {
limit_commits: i32,
limit_snapshot_rows: i32,
max_snapshot_pages: i32,
accept: u8,
},
Subscription {
id: String,
table: String,
scopes: Vec<(String, Vec<String>)>,
params: Option<RawJson>,
cursor: i64,
bootstrap_state: Option<RawJson>,
},
RespHeader {
required_schema_version: Option<i32>,
latest_schema_version: Option<i32>,
},
Lease {
lease_id: String,
expires_at_ms: i64,
},
PushResult {
client_commit_id: String,
status: PushStatus,
commit_seq: Option<i64>,
results: Vec<OpResult>,
},
SubStart {
id: String,
status: SubStatus,
reason_code: String,
effective_scopes: Vec<(String, Vec<String>)>,
bootstrap: bool,
},
Commit {
commit_seq: i64,
created_at_ms: i64,
actor_id: String,
tables: Vec<String>,
changes: Vec<Change>,
},
SegmentRef {
segment_id: String,
media_type: MediaType,
table: String,
byte_length: i64,
row_count: i64,
as_of_commit_seq: i64,
scope_digest: String,
row_cursor: Option<String>,
next_row_cursor: Option<String>,
url: Option<String>,
url_expires_at_ms: Option<i64>,
},
SegmentInline { payload: Vec<u8> },
SubEnd {
next_cursor: i64,
bootstrap_state: Option<RawJson>,
},
Error {
code: String,
message: String,
category: String,
retryable: bool,
recommended_action: String,
details: Option<RawJson>,
},
Unknown { frame_type: u8, payload: Vec<u8> },
}