use std::fmt::Debug;
use std::fmt::Formatter;
use std::marker::PhantomData;
use allocative::Allocative;
use dupe::Clone_;
use dupe::Copy_;
use dupe::Dupe_;
use crate::typing::Ty;
use crate::values::type_repr::StarlarkTypeRepr;
use crate::values::AllocValue;
use crate::values::Heap;
use crate::values::Trace;
use crate::values::Tracer;
use crate::values::UnpackValue;
use crate::values::Value;
#[derive(Clone_, Copy_, Dupe_, Allocative)]
#[allocative(bound = "")]
pub struct ValueOfUnchecked<'v, T: StarlarkTypeRepr>(Value<'v>, PhantomData<T>);
impl<'v, T: StarlarkTypeRepr> Debug for ValueOfUnchecked<'v, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("ValueOfUnchecked").field(&self.0).finish()
}
}
impl<'v, T: StarlarkTypeRepr> ValueOfUnchecked<'v, T> {
#[inline]
pub fn new(value: Value<'v>) -> Self {
Self(value, PhantomData)
}
#[inline]
pub fn new_checked(value: Value<'v>) -> anyhow::Result<Self>
where
T: UnpackValue<'v>,
{
T::unpack_value_err(value)?;
Ok(Self::new(value))
}
#[inline]
pub fn get(self) -> Value<'v> {
self.0
}
}
impl<'v, T: StarlarkTypeRepr> StarlarkTypeRepr for ValueOfUnchecked<'v, T> {
fn starlark_type_repr() -> Ty {
T::starlark_type_repr()
}
}
impl<'v, T: StarlarkTypeRepr> AllocValue<'v> for ValueOfUnchecked<'v, T> {
#[inline]
fn alloc_value(self, _heap: &'v Heap) -> Value<'v> {
self.0
}
}
impl<'v, T: StarlarkTypeRepr> UnpackValue<'v> for ValueOfUnchecked<'v, T> {
#[inline]
fn unpack_value(value: Value<'v>) -> Option<Self> {
Some(Self::new(value))
}
}
unsafe impl<'v, T: StarlarkTypeRepr> Trace<'v> for ValueOfUnchecked<'v, T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
let ValueOfUnchecked(value, phantom) = self;
value.trace(tracer);
phantom.trace(tracer);
}
}