#[allow(unused_imports)]
use crate::{
AccessKind, MapEntryVisitor, Meta, MetaMut, MoveItemError, Object, ObjectRef, ObjectRefMut,
PathSegment, ValueKind,
};
use alloc::string::String;
use alloc::vec::Vec;
pub enum Reflect<'a> {
Scalar,
Struct(&'a dyn StructAccess),
Enum(&'a dyn EnumAccess),
Tuple(&'a dyn TupleAccess),
Sequence(&'a dyn SequenceAccess),
KeyedSequence(&'a dyn KeyedSequenceAccess),
Map(&'a dyn MapAccess),
Option(Option<ObjectRef<'a>>),
}
impl Reflect<'_> {
#[inline]
pub fn kind(&self) -> ValueKind {
match self {
Self::Scalar => ValueKind::Scalar,
Self::Struct(_) => ValueKind::Struct,
Self::Tuple(_) => ValueKind::Tuple,
Self::Enum(_) => ValueKind::Enum,
Self::Sequence(_) | Self::KeyedSequence(_) => ValueKind::Sequence,
Self::Map(_) => ValueKind::Map,
Self::Option(_) => ValueKind::Option,
}
}
}
pub enum ReflectMut<'a> {
Opaque,
Struct(&'a mut dyn StructAccessMut),
Tuple(&'a mut dyn TupleAccessMut),
Enum(&'a mut dyn EnumAccessMut),
Sequence(&'a mut dyn SequenceAccessMut),
KeyedSequence(&'a mut dyn KeyedSequenceAccessMut),
Map(&'a mut dyn MapAccessMut),
Option(&'a mut dyn OptionAccessMut),
}
pub trait StructAccess {
fn field(&self, name: &str) -> Option<ObjectRef<'_>>;
fn field_names(&self) -> &'static [&'static str];
}
#[allow(clippy::len_without_is_empty)]
pub trait TupleAccess {
fn item(&self, index: usize) -> Option<ObjectRef<'_>>;
fn len(&self) -> usize;
}
pub enum VariantFields<'a> {
Unit,
Named(&'a dyn StructAccess),
Positional(&'a dyn TupleAccess),
}
pub trait EnumAccess {
fn variant_name(&self) -> &'static str;
fn fields(&self) -> VariantFields<'_>;
}
#[allow(clippy::len_without_is_empty)]
pub trait SequenceAccess {
fn len(&self) -> usize;
fn item(&self, index: usize) -> Option<ObjectRef<'_>>;
}
pub trait KeyedSequenceAccess: SequenceAccess {
fn key(&self, key: &str) -> Option<ObjectRef<'_>>;
fn keys(&self) -> Vec<String>;
}
#[allow(clippy::len_without_is_empty)]
pub trait MapAccess {
fn len(&self) -> usize;
fn key(&self, key: &str) -> Option<ObjectRef<'_>>;
fn keys(&self) -> Option<Vec<String>>;
fn visit_entries(&self, visitor: &mut MapEntryVisitor<'_>);
}
pub trait StructAccessMut {
fn field_mut(&mut self, name: &str) -> Option<ObjectRefMut<'_>>;
}
pub trait TupleAccessMut {
fn item_mut(&mut self, index: usize) -> Option<ObjectRefMut<'_>>;
}
pub enum VariantFieldsMut<'a> {
Unit,
Named(&'a mut dyn StructAccessMut),
Positional(&'a mut dyn TupleAccessMut),
}
pub trait EnumAccessMut: EnumAccess {
fn fields_mut(&mut self) -> VariantFieldsMut<'_>;
}
pub trait SequenceAccessMut: SequenceAccess {
fn item_mut(&mut self, _index: usize) -> Option<ObjectRefMut<'_>> {
None
}
fn insert_item(&mut self, _index: usize, value: Object) -> Result<ObjectRefMut<'_>, Object> {
Err(value)
}
fn push_item(&mut self, value: Object) -> Result<ObjectRefMut<'_>, Object> {
Err(value)
}
fn remove_item(&mut self, _index: usize) -> Option<Object> {
None
}
fn move_item(&mut self, _from: usize, _to: usize) -> Result<(), MoveItemError> {
Err(MoveItemError::Unsupported)
}
}
pub trait KeyedSequenceAccessMut: SequenceAccessMut + KeyedSequenceAccess {
fn key_mut(&mut self, key: &str) -> Option<ObjectRefMut<'_>>;
}
macro_rules! with_sequence_mut {
($shape:expr, |$sequence:ident| $body:block, $fallback:block) => {
match $shape {
$crate::ReflectMut::Sequence($sequence) => $body,
$crate::ReflectMut::KeyedSequence($sequence) => $body,
_ => $fallback,
}
};
}
pub(crate) use with_sequence_mut;
#[cfg(typex_trait_upcasting)]
macro_rules! with_patch_sequence_mut {
($shape:expr, |$sequence:ident| $body:block, $fallback:block) => {{
let $sequence: &mut dyn $crate::SequenceAccessMut = match $shape {
$crate::ReflectMut::Sequence(sequence) => sequence,
$crate::ReflectMut::KeyedSequence(sequence) => sequence,
_ => $fallback,
};
$body
}};
}
#[cfg(typex_trait_upcasting)]
pub(crate) use with_patch_sequence_mut;
#[cfg(not(typex_trait_upcasting))]
pub(crate) use with_sequence_mut as with_patch_sequence_mut;
pub trait MapAccessMut {
fn key_mut(&mut self, key: &str) -> Option<ObjectRefMut<'_>>;
fn insert_key(&mut self, _key: &str, value: Object) -> Result<ObjectRefMut<'_>, Object> {
Err(value)
}
fn remove_key(&mut self, _key: &str) -> Option<Object> {
None
}
}
pub trait OptionAccessMut {
fn value_mut(&mut self) -> Option<ObjectRefMut<'_>>;
fn insert_value(&mut self, value: Object) -> Result<ObjectRefMut<'_>, Object>;
fn take_value(&mut self) -> Option<Object>;
}