use serde::{Deserialize, Serialize};
use crate::graphql::client_manifest::DISTRIBUTED_CLIENT_PROTOCOL_VERSION;
use super::OpaqueProtocolToken;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum DistributedCommandState {
InProgress,
Succeeded,
SucceededPendingProjection,
Atomic,
Rejected,
ProjectionFailed,
Expired,
Unknown,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum DistributedCommandConsistency {
Succeeded,
Eventual,
Atomic,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub(crate) enum DistributedProjectionDisposition {
Revalidate,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedProjectionExpectation {
pub(crate) projection: String,
pub(crate) model: String,
pub(crate) scope_token: OpaqueProtocolToken,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedCommandMetadata {
pub(crate) command_id: String,
pub(crate) causation_id: String,
pub(crate) state: DistributedCommandState,
pub(crate) consistency: DistributedCommandConsistency,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) projection_disposition: Option<DistributedProjectionDisposition>,
pub(crate) expects: Vec<DistributedProjectionExpectation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) projection: Option<super::CommandProjectionMetadataV1>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub(crate) observations: Vec<DistributedProjectionObservation>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub(crate) records: Vec<DistributedRecordRevision>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedRecordRevision {
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) path: Option<Vec<String>>,
pub(crate) model: String,
pub(crate) scope_token: OpaqueProtocolToken,
pub(crate) incarnation: String,
pub(crate) revision: String,
pub(crate) tombstone: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedProjectionObservation {
pub(crate) causation_id: String,
pub(crate) projection: String,
pub(crate) model: String,
pub(crate) scope_token: OpaqueProtocolToken,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedLiveCursor {
pub(crate) projection: String,
pub(crate) position: String,
pub(crate) token: OpaqueProtocolToken,
}
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub(crate) enum RequestedLiveResume {
#[default]
Absent,
Invalid,
Cursors(Vec<DistributedLiveCursor>),
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedIndexRevision {
pub(crate) projection: String,
pub(crate) scope_token: OpaqueProtocolToken,
pub(crate) position: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) resume: Option<DistributedLiveCursor>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedQuerySnapshot {
pub(crate) scope_token: OpaqueProtocolToken,
pub(crate) records_complete: bool,
pub(crate) indexes_comparable: bool,
pub(crate) records: Vec<DistributedRecordRevision>,
pub(crate) indexes: Vec<DistributedIndexRevision>,
pub(crate) observations: Vec<DistributedProjectionObservation>,
}
impl DistributedQuerySnapshot {
pub(super) fn discard_incomparable_index_evidence(&mut self) {
if self.indexes_comparable {
return;
}
self.indexes.clear();
self.observations.clear();
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedLiveMetadata {
pub(crate) supported: bool,
pub(crate) reset: bool,
pub(crate) cursors: Vec<DistributedLiveCursor>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedTrustedPreset {
pub(crate) name: String,
pub(crate) codec: String,
pub(crate) value: serde_json::Value,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct DistributedEnvelopeV1 {
pub(crate) protocol_version: u32,
pub(crate) schema_hash: String,
pub(crate) authorization_generation: String,
pub(crate) cache_scope: OpaqueProtocolToken,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) operation: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) command: Option<DistributedCommandMetadata>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) snapshot: Option<DistributedQuerySnapshot>,
#[serde(skip_serializing_if = "Option::is_none")]
pub(crate) live: Option<DistributedLiveMetadata>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub(crate) trusted_presets: Vec<DistributedTrustedPreset>,
}
impl DistributedEnvelopeV1 {
pub(crate) fn new(
schema_hash: impl Into<String>,
authorization_generation: impl Into<String>,
cache_scope: OpaqueProtocolToken,
operation: Option<String>,
) -> Self {
Self {
protocol_version: DISTRIBUTED_CLIENT_PROTOCOL_VERSION,
schema_hash: schema_hash.into(),
authorization_generation: authorization_generation.into(),
cache_scope,
operation,
command: None,
snapshot: None,
live: None,
trusted_presets: Vec::new(),
}
}
pub(crate) fn with_trusted_presets(
mut self,
trusted_presets: Vec<DistributedTrustedPreset>,
) -> Self {
self.trusted_presets = trusted_presets;
self
}
}