use crate as starlark;
use crate::coerce::coerce;
use crate::coerce::Coerce;
use crate::typing::Ty;
use crate::values::type_repr::StarlarkTypeRepr;
use crate::values::types::tuple::value::FrozenTuple;
use crate::values::types::tuple::value::Tuple;
use crate::values::FrozenValue;
use crate::values::UnpackValue;
use crate::values::Value;
use crate::values::ValueLike;
#[derive(Coerce, Debug)]
#[repr(transparent)]
pub struct TupleRef<'v> {
contents: [Value<'v>],
}
#[repr(transparent)]
#[derive(Coerce, Debug)]
pub struct FrozenTupleRef {
contents: [FrozenValue],
}
impl<'v> TupleRef<'v> {
pub const TYPE: &'static str = FrozenTupleRef::TYPE;
pub fn from_value(value: Value<'v>) -> Option<&'v TupleRef<'v>> {
Some(coerce(Tuple::from_value(value)?.content()))
}
pub fn from_frozen_value(value: FrozenValue) -> Option<&'v TupleRef<'v>> {
Self::from_value(value.to_value())
}
pub fn len(&self) -> usize {
self.contents.len()
}
pub fn content(&self) -> &[Value<'v>] {
&self.contents
}
pub fn iter(&self) -> impl ExactSizeIterator<Item = Value<'v>> + '_ {
self.content().iter().copied()
}
}
impl FrozenTupleRef {
pub const TYPE: &'static str = FrozenTuple::TYPE;
pub fn from_frozen_value(value: FrozenValue) -> Option<&'static FrozenTupleRef> {
Some(coerce(value.downcast_ref::<FrozenTuple>()?.content()))
}
pub fn len(&self) -> usize {
self.contents.len()
}
pub fn content(&self) -> &[FrozenValue] {
&self.contents
}
pub fn iter(&self) -> impl ExactSizeIterator<Item = FrozenValue> + '_ {
self.content().iter().copied()
}
}
impl<'v> StarlarkTypeRepr for &'v TupleRef<'v> {
fn starlark_type_repr() -> Ty {
Ty::any_tuple()
}
}
impl<'a> StarlarkTypeRepr for &'a FrozenTupleRef {
fn starlark_type_repr() -> Ty {
Ty::any_tuple()
}
}
impl<'v> UnpackValue<'v> for &'v TupleRef<'v> {
fn unpack_value(value: Value<'v>) -> Option<Self> {
TupleRef::from_value(value)
}
}
impl<'v> UnpackValue<'v> for &'v FrozenTupleRef {
fn unpack_value(value: Value<'v>) -> Option<Self> {
FrozenTupleRef::from_frozen_value(value.unpack_frozen()?)
}
}