use crate::typing::Ty;
use crate::values::starlark_type_id::StarlarkTypeId;
use crate::values::structs::value::FrozenStruct;
use crate::values::structs::value::Struct;
use crate::values::type_repr::StarlarkTypeRepr;
use crate::values::FrozenStringValue;
use crate::values::FrozenValue;
use crate::values::StringValue;
use crate::values::UnpackValue;
use crate::values::Value;
#[derive(Debug)]
pub struct StructRef<'v>(&'v Struct<'v>);
impl<'v> StructRef<'v> {
pub fn from_value(value: Value<'v>) -> Option<StructRef<'v>> {
Struct::from_value(value).map(StructRef)
}
#[inline]
pub(crate) fn is_instance(value: Value<'v>) -> bool {
debug_assert!(StarlarkTypeId::of::<Struct>() == StarlarkTypeId::of::<FrozenStruct>());
value.starlark_type_id() == StarlarkTypeId::of::<Struct>()
}
pub fn iter(&self) -> impl ExactSizeIterator<Item = (StringValue<'v>, Value<'v>)> + '_ {
self.0.iter()
}
}
impl<'v> StarlarkTypeRepr for StructRef<'v> {
fn starlark_type_repr() -> Ty {
FrozenStruct::starlark_type_repr()
}
}
impl<'v> UnpackValue<'v> for StructRef<'v> {
fn unpack_value(value: Value<'v>) -> Option<Self> {
StructRef::from_value(value)
}
}
#[derive(Debug)]
pub struct FrozenStructRef<'f>(&'f FrozenStruct);
impl<'f> FrozenStructRef<'f> {
pub fn iter(&self) -> impl ExactSizeIterator<Item = (FrozenStringValue, FrozenValue)> + 'f {
self.0.iter_frozen()
}
pub fn from_value(value: FrozenValue) -> Option<FrozenStructRef<'f>> {
value
.downcast_frozen_ref::<FrozenStruct>()
.map(|f| FrozenStructRef(f.as_ref()))
}
}