use crate::prelude::*;
use icydb_schema::ScalarKind;
use std::str::FromStr;
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub enum Cardinality {
#[default]
One,
Opt,
Many,
}
impl FromStr for Cardinality {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"One" => Ok(Self::One),
"Opt" => Ok(Self::Opt),
"Many" => Ok(Self::Many),
_ => Err("unknown Cardinality"),
}
}
}
macro_rules! define_primitive {
( @entries $( ($primitive:ident, $scalar:ident) ),* $(,)? ) => {
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[remain::sorted]
pub enum Primitive {
$( $primitive, )*
}
impl FromStr for Primitive {
type Err = &'static str;
fn from_str(value: &str) -> Result<Self, Self::Err> {
match value {
$( stringify!($primitive) => Ok(Self::$primitive), )*
_ => Err("unknown Primitive"),
}
}
}
const fn primitive_scalar_kind(primitive: Primitive) -> ScalarKind {
match primitive {
$( Primitive::$primitive => ScalarKind::$scalar, )*
}
}
};
}
icydb_schema::authoring_primitive_registry!(define_primitive);
impl Primitive {
#[must_use]
pub const fn is_primary_key_component_encodable(self) -> bool {
primitive_scalar_kind(self).is_primary_key_component_encodable()
}
}
#[cfg(test)]
mod tests {
use super::{Primitive, primitive_scalar_kind};
use icydb_schema::ScalarKind;
macro_rules! define_primitive_cases {
( @entries $( ($primitive:ident, $scalar:ident) ),* $(,)? ) => {
const PRIMITIVE_CASES: &[(&str, Primitive, ScalarKind)] = &[
$(
(
stringify!($primitive),
Primitive::$primitive,
ScalarKind::$scalar,
),
)*
];
};
}
icydb_schema::authoring_primitive_registry!(define_primitive_cases);
#[test]
fn primitive_catalog_parses_and_maps_to_scalar_kinds() {
for &(name, primitive, scalar_kind) in PRIMITIVE_CASES {
assert_eq!(name.parse(), Ok(primitive));
assert_eq!(primitive_scalar_kind(primitive), scalar_kind);
}
assert_eq!("Unknown".parse::<Primitive>(), Err("unknown Primitive"));
}
}