use crate::facet::applied::AppliedAnnotation;
use crate::node::constant::ConstExprNode;
use alloc::string::String;
use alloc::vec::Vec;
use zerodds_ast_core::Id;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub enum Extensibility {
Final,
Appendable,
Mutable,
}
impl Extensibility {
pub const ALL: [Self; 3] = [Self::Final, Self::Appendable, Self::Mutable];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Final => "final",
Self::Appendable => "appendable",
Self::Mutable => "mutable",
}
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
match value {
"final" => Some(Self::Final),
"appendable" => Some(Self::Appendable),
"mutable" => Some(Self::Mutable),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TryConstruct {
Discard,
UseDefault,
Trim,
}
impl TryConstruct {
pub const ALL: [Self; 3] = [Self::Discard, Self::UseDefault, Self::Trim];
pub const ABSENT: Self = Self::Discard;
pub const BARE: Self = Self::UseDefault;
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Discard => "DISCARD",
Self::UseDefault => "USE_DEFAULT",
Self::Trim => "TRIM",
}
}
#[must_use]
pub fn parse(value: &str) -> Option<Self> {
Self::ALL
.into_iter()
.find(|behaviour| behaviour.as_str() == value)
}
#[must_use]
pub const fn trim_is_defined_for(kind: &crate::TypeKind) -> bool {
matches!(
kind,
crate::TypeKind::String { .. }
| crate::TypeKind::Sequence { .. }
| crate::TypeKind::Map { .. }
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MemberIdOrigin {
Declared,
Hashed {
source_name: String,
},
AutoSequential,
AutoHash,
PreviousPlusOne,
}
impl MemberIdOrigin {
#[must_use]
pub const fn as_str(&self) -> &'static str {
match self {
Self::Declared => "@id",
Self::Hashed { .. } => "@hashid",
Self::AutoSequential => "@autoid(SEQUENTIAL)",
Self::AutoHash => "@autoid(HASH)",
Self::PreviousPlusOne => "previous member + 1",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MemberIdAssignment {
pub effective: u32,
pub origin: MemberIdOrigin,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum VerbatimPlacement {
BeginFile,
BeforeDeclaration,
BeginDeclaration,
EndDeclaration,
AfterDeclaration,
EndFile,
}
impl VerbatimPlacement {
pub const ALL: [Self; 6] = [
Self::BeginFile,
Self::BeforeDeclaration,
Self::BeginDeclaration,
Self::EndDeclaration,
Self::AfterDeclaration,
Self::EndFile,
];
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct VerbatimDirective {
pub language: String,
pub placement: VerbatimPlacement,
pub text: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RangeConstraint {
pub min: Option<Id<ConstExprNode>>,
pub max: Option<Id<ConstExprNode>>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct XTypesFacet {
pub extensibility: Option<Extensibility>,
pub is_key: bool,
pub is_optional: bool,
pub is_external: bool,
pub is_must_understand: bool,
pub escaped: bool,
pub is_non_serialized: bool,
pub is_nested: bool,
pub element_is_external: bool,
pub key_is_external: bool,
pub nested_explicit: bool,
pub is_default_literal: bool,
pub try_construct: Option<TryConstruct>,
pub element_try_construct: Option<TryConstruct>,
pub key_try_construct: Option<TryConstruct>,
pub default_nested: Option<bool>,
pub discriminator_try_construct: Option<TryConstruct>,
pub element_annotations: Vec<AppliedAnnotation>,
pub key_annotations: Vec<AppliedAnnotation>,
pub discriminator_annotations: Vec<AppliedAnnotation>,
pub discriminator_is_key: bool,
pub member_id: Option<MemberIdAssignment>,
pub bit_bound: Option<u16>,
pub default_value: Option<Id<ConstExprNode>>,
pub range: Option<RangeConstraint>,
pub unit: Option<String>,
pub verbatim: Vec<VerbatimDirective>,
pub autoid: Option<AutoId>,
pub topic: Option<TopicAnnotation>,
pub data_representation: Option<DataRepresentationMask>,
pub ignore_literal_names: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AutoId {
Sequential,
Hash,
}
impl AutoId {
pub const ALL: [Self; 2] = [Self::Sequential, Self::Hash];
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Sequential => "SEQUENTIAL",
Self::Hash => "HASH",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct TopicAnnotation {
pub name: Option<String>,
pub platform: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct DataRepresentationMask {
pub xcdr1: bool,
pub xcdr2: bool,
pub xml: bool,
}
impl DataRepresentationMask {
pub const ALL: Self = Self {
xcdr1: true,
xcdr2: true,
xml: true,
};
pub const ALL_BITS: u32 = 0xffff_ffff;
#[must_use]
pub const fn bits(self) -> u32 {
(self.xcdr1 as u32) | ((self.xml as u32) << 1) | ((self.xcdr2 as u32) << 2)
}
#[must_use]
pub const fn is_empty(self) -> bool {
!self.xcdr1 && !self.xcdr2 && !self.xml
}
}
impl XTypesFacet {
#[must_use]
pub fn effective_member_id(&self) -> Option<u32> {
self.member_id.as_ref().map(|a| a.effective)
}
}