use std::marker::PhantomData;
use crate::pagable::StaticValueRegistered;
use crate::values::FreezeResult;
use crate::values::Freezer;
use crate::values::FrozenValue;
use crate::values::FrozenValueTyped;
use crate::values::StarlarkValue;
use crate::values::Tracer;
use crate::values::Value;
use crate::values::any::FrozenAnyValue;
use crate::values::any::StarlarkAnyRegistered;
use crate::values::layout::avalue::AValue;
use crate::values::layout::avalue::AValueImpl;
use crate::values::layout::heap::repr::AValueRepr;
use crate::values::layout::vtable::AValueVTable;
use crate::values::types::any::StarlarkAny;
pub(crate) struct AValueBasic<T>(PhantomData<T>);
impl<'v, T: StarlarkValue<'v>> AValue<'v> for AValueBasic<T> {
type StarlarkValue = T;
type ExtraElem = ();
fn extra_len(_value: &T) -> usize {
unreachable!("Basic types don't appear in the heap")
}
fn offset_of_extra() -> usize {
unreachable!("Basic types don't appear in the heap")
}
unsafe fn heap_freeze(
_me: *mut AValueRepr<Self::StarlarkValue>,
_freezer: &Freezer,
) -> FreezeResult<FrozenValue> {
unreachable!("Basic types don't appear in the heap")
}
unsafe fn heap_copy(
_me: *mut AValueRepr<Self::StarlarkValue>,
_tracer: &Tracer<'v>,
) -> Value<'v> {
unreachable!("Basic types don't appear in the heap")
}
fn total_memory_for_profile(_value: &Self::StarlarkValue) -> usize {
0
}
}
pub struct AllocStaticSimple<T: StarlarkValue<'static>>(
AValueRepr<AValueImpl<'static, AValueBasic<T>>>,
);
impl<T: StarlarkValue<'static>> AllocStaticSimple<T> {
pub const fn alloc(value: T) -> Self
where
T: StaticValueRegistered,
{
AllocStaticSimple(AValueRepr::with_metadata(
AValueVTable::new::<AValueBasic<T>>(),
AValueImpl::<AValueBasic<T>>::new(value),
))
}
pub fn unpack(&'static self) -> FrozenValueTyped<'static, T> {
FrozenValueTyped::new_repr(&self.0)
}
pub fn to_frozen_value(&'static self) -> FrozenValue {
self.unpack().to_frozen_value()
}
pub const fn as_payload(&'static self) -> &'static T {
&self.0.payload.1
}
}
impl<T: StarlarkAnyRegistered> AllocStaticSimple<StarlarkAny<T>> {
pub fn unpack_any(&'static self) -> FrozenAnyValue<T> {
FrozenAnyValue::from_typed(self.unpack())
}
}
#[cfg(test)]
mod tests {
use allocative::Allocative;
use starlark_derive::NoSerialize;
use starlark_derive::ProvidesStaticType;
use starlark_derive::StarlarkPagable;
use starlark_derive::starlark_value;
use crate as starlark;
use crate::values::AllocStaticSimple;
use crate::values::StarlarkValue;
use crate::values::StaticValueRegistered;
#[test]
fn test_alloc_static_simple() {
#[derive(
Debug,
derive_more::Display,
ProvidesStaticType,
NoSerialize,
Allocative,
StarlarkPagable
)]
#[display("MySimpleValue")]
struct MySimpleValue(u32);
unsafe impl StaticValueRegistered for MySimpleValue {}
#[starlark_value(type = "MySimpleValue", skip_pagable)]
impl<'v> StarlarkValue<'v> for MySimpleValue {}
static VALUE: AllocStaticSimple<MySimpleValue> =
AllocStaticSimple::alloc(MySimpleValue(17));
assert_eq!(17, VALUE.unpack().as_ref().0);
}
}