use super::*;
#[repr(u8)]
#[derive(Copy, Clone, StableAbi)]
#[sabi(unsafe_sabi_opaque_fields)]
pub enum MonoTLData {
Primitive(TLPrimitive),
Opaque,
Struct {
fields: CompTLFields
},
Union {
fields: CompTLFields
},
Enum (MonoTLEnum),
PrefixType(MonoTLPrefixType),
}
impl MonoTLData {
pub const EMPTY:Self=
MonoTLData::Struct {
fields: CompTLFields::EMPTY,
};
pub const fn struct_(fields: RSlice<'static,CompTLField>) -> Self {
MonoTLData::Struct {
fields: CompTLFields::from_fields(fields),
}
}
#[doc(hidden)]
pub const fn derive_struct(fields: CompTLFields) -> Self {
MonoTLData::Struct {
fields,
}
}
pub const fn union_(fields: RSlice<'static,CompTLField>) -> Self {
MonoTLData::Union {
fields: CompTLFields::from_fields(fields),
}
}
#[doc(hidden)]
pub const fn derive_union(fields: CompTLFields) -> Self {
MonoTLData::Union {
fields,
}
}
pub const fn prefix_type(
first_suffix_field:usize,
conditional_prefix_fields:FieldConditionality,
fields: RSlice<'static,CompTLField>,
)->Self{
MonoTLData::PrefixType(MonoTLPrefixType{
first_suffix_field:first_suffix_field as u8,
conditional_prefix_fields,
fields: CompTLFields::from_fields(fields),
})
}
pub const fn struct_derive(fields: CompTLFields) -> Self {
MonoTLData::Struct {
fields,
}
}
pub const fn union_derive(fields: CompTLFields) -> Self {
MonoTLData::Union {
fields,
}
}
pub const fn prefix_type_derive(
first_suffix_field:usize,
conditional_prefix_fields:u64,
fields: CompTLFields,
)->Self{
MonoTLData::PrefixType(MonoTLPrefixType{
first_suffix_field:first_suffix_field as u8,
conditional_prefix_fields:FieldConditionality::from_u64(conditional_prefix_fields),
fields,
})
}
pub fn as_discriminant(&self) -> TLDataDiscriminant {
match self {
MonoTLData::Primitive { .. } => TLDataDiscriminant::Primitive,
MonoTLData::Opaque { .. } => TLDataDiscriminant::Opaque,
MonoTLData::Struct { .. } => TLDataDiscriminant::Struct,
MonoTLData::Union { .. } => TLDataDiscriminant::Union,
MonoTLData::Enum { .. } => TLDataDiscriminant::Enum,
MonoTLData::PrefixType { .. } => TLDataDiscriminant::PrefixType,
}
}
pub(super) fn to_primitive(&self)->Option<TLPrimitive>{
match self {
MonoTLData::Primitive(x)=>Some(*x),
_=>None,
}
}
pub fn expand(
self,
generic:GenericTLData,
shared_vars:&'static SharedVars
)-> Result<TLData,MismatchedTLDataVariant> {
Ok(match (self,generic) {
( MonoTLData::Primitive(prim), GenericTLData::Primitive )=>{
TLData::Primitive(prim)
},
( MonoTLData::Opaque, GenericTLData::Opaque )=>{
TLData::Opaque
},
( MonoTLData::Struct{fields}, GenericTLData::Struct )=>{
TLData::Struct{
fields:fields.expand(shared_vars)
}
},
( MonoTLData::Union{fields}, GenericTLData::Union )=>{
TLData::Union{
fields:fields.expand(shared_vars)
}
},
( MonoTLData::Enum(nongeneric), GenericTLData::Enum(generic) )=>{
TLData::Enum(nongeneric.expand(generic,shared_vars))
},
( MonoTLData::PrefixType(nongeneric), GenericTLData::PrefixType(generic) )=>{
TLData::PrefixType(nongeneric.expand(generic,shared_vars))
},
_=>{
return Err(MismatchedTLDataVariant{
nongeneric: self.as_discriminant(),
generic: generic.as_discriminant(),
})
}
})
}
}
#[derive(Debug,Clone)]
pub struct MismatchedTLDataVariant{
nongeneric: TLDataDiscriminant,
generic: TLDataDiscriminant,
}
impl Display for MismatchedTLDataVariant{
fn fmt(&self,f:&mut fmt::Formatter<'_>)->fmt::Result {
writeln!(
f,
"Error combining TLData::{:?} and GenericTLData::{:?}",
self.nongeneric,
self.generic,
)
}
}
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, StableAbi)]
#[sabi(unsafe_sabi_opaque_fields)]
pub enum TLDataDiscriminant {
Primitive,
Opaque,
Struct,
Union,
Enum,
PrefixType,
}
#[repr(C)]
#[derive(Copy, Clone, StableAbi)]
#[sabi(unsafe_sabi_opaque_fields)]
pub enum GenericTLData {
Primitive,
Opaque,
Struct,
Union,
Enum(GenericTLEnum),
PrefixType(GenericTLPrefixType),
}
impl GenericTLData{
pub fn as_discriminant(&self) -> TLDataDiscriminant {
match self {
GenericTLData::Primitive { .. } => TLDataDiscriminant::Primitive,
GenericTLData::Opaque { .. } => TLDataDiscriminant::Opaque,
GenericTLData::Struct { .. } => TLDataDiscriminant::Struct,
GenericTLData::Union { .. } => TLDataDiscriminant::Union,
GenericTLData::Enum { .. } => TLDataDiscriminant::Enum,
GenericTLData::PrefixType { .. } => TLDataDiscriminant::PrefixType,
}
}
#[doc(hidden)]
pub const fn prefix_type_derive(
accessible_fields:FieldAccessibility,
)->Self{
GenericTLData::PrefixType(GenericTLPrefixType{
accessible_fields,
})
}
}
#[derive(Debug,Copy,Clone,PartialEq,Eq)]
pub enum TLData{
Primitive(TLPrimitive),
Opaque,
Struct {
fields: TLFields
},
Union {
fields: TLFields
},
Enum(TLEnum),
PrefixType(TLPrefixType),
}
impl Display for TLData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TLData::Primitive(prim)=>{
writeln!(f,"Primitive:{:?}",prim)?;
},
TLData::Opaque=>{
writeln!(f,"Opaque data")?;
},
TLData::Struct{fields}=>{
writeln!(f,"Struct with Fields:\n{}",fields.to_string().left_padder(4))?;
},
TLData::Union{fields}=>{
writeln!(f,"Union with Fields:\n{}",fields.to_string().left_padder(4))?;
},
TLData::Enum (enum_)=>{
writeln!(f,"Enum:")?;
Display::fmt(enum_,f)?;
},
TLData::PrefixType(prefix)=>{
writeln!(f,"Prefix type:")?;
Display::fmt(prefix,f)?;
}
}
Ok(())
}
}