use std::ops::Deref;
use dupe::Dupe;
use crate::typing::Ty;
use crate::values::type_repr::StarlarkTypeRepr;
use crate::values::AllocValue;
use crate::values::Heap;
use crate::values::UnpackValue;
use crate::values::Value;
use crate::values::ValueOfUnchecked;
#[derive(Debug, Copy, Clone, Dupe)]
pub struct ValueOf<'v, T: UnpackValue<'v>> {
pub value: Value<'v>,
pub typed: T,
}
impl<'v, T: UnpackValue<'v>> ValueOf<'v, T> {
pub fn as_unchecked(&self) -> ValueOfUnchecked<'v, T> {
ValueOfUnchecked::new(self.value)
}
}
impl<'v, T: UnpackValue<'v>> Deref for ValueOf<'v, T> {
type Target = Value<'v>;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<'v, T: UnpackValue<'v>> StarlarkTypeRepr for ValueOf<'v, T> {
type Canonical = T::Canonical;
fn starlark_type_repr() -> Ty {
T::starlark_type_repr()
}
}
impl<'v, T: UnpackValue<'v>> UnpackValue<'v> for ValueOf<'v, T> {
type Error = T::Error;
fn unpack_value_impl(value: Value<'v>) -> Result<Option<Self>, Self::Error> {
let Some(typed) = T::unpack_value_impl(value)? else {
return Ok(None);
};
Ok(Some(Self { value, typed }))
}
}
impl<'v, T: UnpackValue<'v>> AllocValue<'v> for ValueOf<'v, T> {
fn alloc_value(self, _heap: &'v Heap) -> Value<'v> {
self.value
}
}