use crate::{
abi_stability::{PrefixStableAbi, StableAbi},
reflection::ModReflMode,
type_layout::{TLData,FieldAccessor,TLField},
std_types::*,
};
#[repr(u8)]
#[derive(StableAbi)]
pub enum PubEnum {
Variant0,
Variant1(RString),
Variant2{
field0:u32,
},
}
#[repr(C)]
#[derive(StableAbi)]
#[allow(dead_code)]
enum PrivEnum {
Variant0,
Variant1(RString),
Variant2{
field0:u32,
},
}
#[repr(C)]
#[derive(StableAbi)]
pub struct RegularPubFields {
pub field0: u8,
pub field1: u8,
#[sabi(refl(pub_getter="what_the"))]
pub field2: u8,
}
#[repr(C)]
#[derive(StableAbi)]
#[sabi(module_reflection( Opaque ))]
pub struct RegularPubFieldsOpaque {
pub field0: u8,
pub field1: u8,
}
#[repr(C)]
#[derive(StableAbi)]
pub struct RegularMostPrivacies {
pub field0: u8,
pub(super)field1: u16,
field2: u32,
}
#[repr(C)]
#[derive(StableAbi)]
pub struct RegularPriv {
field0: u8,
field1: u16,
#[sabi(refl(pub_getter="hello"))]
field2: u32,
}
#[repr(C)]
#[derive(StableAbi)]
#[sabi(
kind(Prefix),
missing_field(panic),
)]
pub struct PrefixPubFields {
#[sabi(last_prefix_field)]
pub field0: u8,
pub field1: u8,
#[sabi(missing_field(option))]
pub field2: u8,
#[sabi(refl(pub_getter="hello"))]
#[sabi(missing_field(default))]
pub field3: u8,
#[sabi(missing_field(panic))]
pub field4: u8,
}
#[repr(C)]
#[derive(StableAbi)]
#[sabi(
kind(Prefix),
missing_field(panic),
module_reflection(Opaque),
)]
pub struct PrefixPubFieldsOpaque {
#[sabi(last_prefix_field)]
pub field0: u8,
#[sabi(missing_field(panic))]
pub field1: u8,
}
#[allow(dead_code)]
mod some_prefixes{
#[repr(C)]
#[derive(StableAbi)]
#[sabi(kind(Prefix))]
pub struct PrefMostPrivacies {
pub field0: u8,
#[sabi(last_prefix_field)]
pub field1: u8,
pub field2: u8,
pub field3: u8,
pub(super)field4: u16,
#[sabi(missing_field(default))]
field5: u32,
}
#[repr(C)]
#[derive(StableAbi)]
#[sabi(kind(Prefix))]
pub struct PrefPriv {
field0: u8,
pub(super) field1: u16,
#[sabi(last_prefix_field)]
#[sabi(missing_field(default))]
pub(crate) field2: u32,
}
}
pub use self::some_prefixes::*;
fn check_fields(
fields:&[TLField],
accessors:&[FieldAccessor],
){
for (field,expec_acc) in fields.iter().zip( accessors ) {
assert_eq!(
field.field_accessor(),
*expec_acc,
"field:{}\nfields:{:#?}",
field.name(),
fields
);
}
}
fn check_enum_accessors<T>(
mod_refl_mode:ModReflMode,
accessors:&[&[FieldAccessor]],
)where
T:StableAbi
{
let layout=T::LAYOUT;
let mut fields=match layout.data() {
TLData::Enum(enum_)=>enum_.fields.iter(),
x=>panic!("layout.data must be TLData::Struct{{..}}:\n{:#?}",x)
};
assert_eq!(layout.mod_refl_mode(),mod_refl_mode);
for expec_vari in accessors {
let subfields=fields.by_ref().take(expec_vari.len()).collect::<Vec<_>>();
check_fields(&subfields,expec_vari)
}
}
fn check_struct_accessors<T>(
mod_refl_mode:ModReflMode,
accessors:&[FieldAccessor],
)where
T:StableAbi
{
let layout=T::LAYOUT;
let fields=match layout.data() {
TLData::Struct{fields}=>fields.to_vec(),
x=>panic!("layout.data must be TLData::Struct{{..}}:\n{:#?}",x)
};
assert_eq!(layout.mod_refl_mode(),mod_refl_mode);
check_fields(&fields,accessors);
}
fn check_prefix_accessors<T>(
mod_refl_mode:ModReflMode,
accessors:&[FieldAccessor],
)where
T:PrefixStableAbi
{
let layout=T::LAYOUT;
let fields=match layout.data() {
TLData::PrefixType(prefix)=>prefix.fields.to_vec(),
x=>panic!("layout.data must be TLData::Struct{{..}}:\n{:#?}",x)
};
assert_eq!(layout.mod_refl_mode(),mod_refl_mode);
check_fields(&fields,accessors);
}
#[test]
fn test_pub_enum(){
check_enum_accessors::<PubEnum>(
ModReflMode::Module,
&[
&[],
&[FieldAccessor::Direct],
&[FieldAccessor::Direct],
]
);
}
#[test]
fn test_priv_enum(){
check_enum_accessors::<PrivEnum>(
ModReflMode::Opaque,
&[
&[],
&[FieldAccessor::Opaque],
&[FieldAccessor::Opaque],
]
);
}
#[test]
fn test_regular_pub_fields(){
check_struct_accessors::<RegularPubFields>(
ModReflMode::Module,
&[
FieldAccessor::Direct,
FieldAccessor::Direct,
{const FA:FieldAccessor=FieldAccessor::method_named(rstr!("what_the"));FA},
]
);
}
#[test]
fn test_regular_pub_fields_opaque(){
check_struct_accessors::<RegularPubFieldsOpaque>(
ModReflMode::Opaque,
&[
FieldAccessor::Opaque,
FieldAccessor::Opaque,
]
);
}
#[test]
fn test_regular_most_privacies(){
check_struct_accessors::<RegularMostPrivacies>(
ModReflMode::Module,
&[
FieldAccessor::Direct,
FieldAccessor::Opaque,
FieldAccessor::Opaque,
]
);
}
#[test]
fn test_regular_priv(){
check_struct_accessors::<RegularPriv>(
ModReflMode::Opaque,
&[
FieldAccessor::Opaque,
FieldAccessor::Opaque,
{const FA:FieldAccessor=FieldAccessor::method_named(rstr!("hello"));FA},
]
);
}
#[test]
fn test_prefix_pub_fields(){
check_prefix_accessors::<PrefixPubFields_Prefix>(
ModReflMode::Module,
&[
FieldAccessor::Method,
FieldAccessor::Method,
FieldAccessor::MethodOption,
{const FA:FieldAccessor=FieldAccessor::method_named(rstr!("hello"));FA},
FieldAccessor::Method,
]
);
}
#[test]
fn test_prefix_pub_fields_opaque(){
check_prefix_accessors::<PrefixPubFieldsOpaque_Prefix>(
ModReflMode::Opaque,
&[
FieldAccessor::Opaque,
FieldAccessor::Opaque,
]
);
}
#[test]
fn test_prefix_most_privacies(){
check_prefix_accessors::<PrefMostPrivacies_Prefix>(
ModReflMode::Module,
&[
FieldAccessor::Method,
FieldAccessor::Method,
FieldAccessor::MethodOption,
FieldAccessor::MethodOption,
FieldAccessor::Opaque,
FieldAccessor::Opaque,
]
);
}
#[test]
fn test_prefix_priv(){
check_prefix_accessors::<PrefPriv_Prefix>(
ModReflMode::Opaque,
&[
FieldAccessor::Opaque,
FieldAccessor::Opaque,
FieldAccessor::Opaque,
]
);
}