use crate::{
db::schema::composite_catalog::CompositeTypeId,
db::schema::{FieldStorageDecode, LeafCodec, ScalarCodec},
types::EntityTag,
value::EnumTypeId,
};
#[derive(Clone, Debug, Eq, PartialEq)]
pub(in crate::db) enum AcceptedFieldKind {
Account,
Blob {
max_len: Option<u32>,
},
Bool,
Date,
Decimal {
scale: u32,
},
Duration,
Enum {
type_id: EnumTypeId,
},
Float32,
Float64,
Int8,
Int16,
Int32,
Int64,
Int128,
IntBig {
max_bytes: u32,
},
Principal,
Subaccount,
Text {
max_len: Option<u32>,
},
Timestamp,
Nat8,
Nat16,
Nat32,
Nat64,
Nat128,
NatBig {
max_bytes: u32,
},
Ulid,
Unit,
Relation {
target_path: String,
target_entity_name: String,
target_entity_tag: EntityTag,
target_store_path: String,
key_kind: Box<Self>,
},
List(Box<Self>),
Set(Box<Self>),
Map {
key: Box<Self>,
value: Box<Self>,
},
Composite {
type_id: CompositeTypeId,
},
}
impl AcceptedFieldKind {
#[must_use]
pub(in crate::db) const fn leaf_codec_for_storage(
&self,
storage_decode: FieldStorageDecode,
) -> LeafCodec {
if matches!(storage_decode, FieldStorageDecode::CatalogValue) {
return LeafCodec::Structural;
}
match self {
Self::Blob { .. } => LeafCodec::Scalar(ScalarCodec::Blob),
Self::Bool => LeafCodec::Scalar(ScalarCodec::Bool),
Self::Date => LeafCodec::Scalar(ScalarCodec::Date),
Self::Duration => LeafCodec::Scalar(ScalarCodec::Duration),
Self::Float32 => LeafCodec::Scalar(ScalarCodec::Float32),
Self::Float64 => LeafCodec::Scalar(ScalarCodec::Float64),
Self::Int8 | Self::Int16 | Self::Int32 | Self::Int64 => {
LeafCodec::Scalar(ScalarCodec::Int64)
}
Self::Principal => LeafCodec::Scalar(ScalarCodec::Principal),
Self::Subaccount => LeafCodec::Scalar(ScalarCodec::Subaccount),
Self::Text { .. } => LeafCodec::Scalar(ScalarCodec::Text),
Self::Timestamp => LeafCodec::Scalar(ScalarCodec::Timestamp),
Self::Nat8 | Self::Nat16 | Self::Nat32 | Self::Nat64 => {
LeafCodec::Scalar(ScalarCodec::Nat64)
}
Self::Ulid => LeafCodec::Scalar(ScalarCodec::Ulid),
Self::Unit => LeafCodec::Scalar(ScalarCodec::Unit),
Self::Account
| Self::Composite { .. }
| Self::Decimal { .. }
| Self::Enum { .. }
| Self::Int128
| Self::IntBig { .. }
| Self::List(_)
| Self::Map { .. }
| Self::Nat128
| Self::NatBig { .. }
| Self::Relation { .. }
| Self::Set(_) => LeafCodec::Structural,
}
}
#[cfg(test)]
#[must_use]
pub(in crate::db) const fn test_composite() -> Self {
Self::Composite {
type_id: CompositeTypeId::new(1).expect("test composite type ID is non-zero"),
}
}
#[must_use]
#[cfg(any(test, feature = "sql"))]
pub(in crate::db) fn contains_enum(&self) -> bool {
match self {
Self::Enum { .. } => true,
Self::Relation { key_kind, .. } | Self::List(key_kind) | Self::Set(key_kind) => {
key_kind.contains_enum()
}
Self::Map { key, value } => key.contains_enum() || value.contains_enum(),
Self::Composite { .. }
| Self::Account
| Self::Blob { .. }
| Self::Bool
| Self::Date
| Self::Decimal { .. }
| Self::Duration
| Self::Float32
| Self::Float64
| Self::Int8
| Self::Int16
| Self::Int32
| Self::Int64
| Self::Int128
| Self::IntBig { .. }
| Self::Principal
| Self::Subaccount
| Self::Text { .. }
| Self::Timestamp
| Self::Nat8
| Self::Nat16
| Self::Nat32
| Self::Nat64
| Self::Nat128
| Self::NatBig { .. }
| Self::Ulid
| Self::Unit => false,
}
}
#[must_use]
#[cfg(any(test, feature = "sql"))]
pub(in crate::db) fn contains_relation(&self) -> bool {
match self {
Self::Relation { .. } => true,
Self::List(inner) | Self::Set(inner) => inner.contains_relation(),
Self::Account
| Self::Blob { .. }
| Self::Bool
| Self::Composite { .. }
| Self::Date
| Self::Decimal { .. }
| Self::Duration
| Self::Enum { .. }
| Self::Float32
| Self::Float64
| Self::Int8
| Self::Int16
| Self::Int32
| Self::Int64
| Self::Int128
| Self::IntBig { .. }
| Self::Map { .. }
| Self::Principal
| Self::Subaccount
| Self::Text { .. }
| Self::Timestamp
| Self::Nat8
| Self::Nat16
| Self::Nat32
| Self::Nat64
| Self::Nat128
| Self::NatBig { .. }
| Self::Ulid
| Self::Unit => false,
}
}
#[must_use]
pub(in crate::db) fn requires_canonical_value_wire(&self) -> bool {
match self {
Self::Enum { .. } | Self::Composite { .. } => true,
Self::Relation { key_kind, .. } | Self::List(key_kind) | Self::Set(key_kind) => {
key_kind.requires_canonical_value_wire()
}
Self::Map { key, value } => {
key.requires_canonical_value_wire() || value.requires_canonical_value_wire()
}
Self::Account
| Self::Blob { .. }
| Self::Bool
| Self::Date
| Self::Decimal { .. }
| Self::Duration
| Self::Float32
| Self::Float64
| Self::Int8
| Self::Int16
| Self::Int32
| Self::Int64
| Self::Int128
| Self::IntBig { .. }
| Self::Principal
| Self::Subaccount
| Self::Text { .. }
| Self::Timestamp
| Self::Nat8
| Self::Nat16
| Self::Nat32
| Self::Nat64
| Self::Nat128
| Self::NatBig { .. }
| Self::Ulid
| Self::Unit => false,
}
}
}