use pagable::PagableDeserialize;
use pagable::PagableDeserializer;
use pagable::PagableSerialize;
use pagable::PagableSerializer;
use crate::pagable::heap_ref_id::HeapRefId;
use crate::pagable::static_value::StaticValueId;
use crate::values::layout::heap::arena::ArenaOffset;
#[derive(Debug)]
pub(super) enum SerializedFrozenValue {
HeapPtr {
heap_id: HeapRefId,
offset: ArenaOffset,
is_str: bool,
},
InlineInt(i32),
Static(StaticValueId),
}
const TAG_HEAP_PTR: u8 = 0;
const TAG_INLINE_INT: u8 = 1;
const TAG_STATIC: u8 = 2;
impl PagableSerialize for SerializedFrozenValue {
fn pagable_serialize(&self, serializer: &mut dyn PagableSerializer) -> pagable::Result<()> {
match self {
SerializedFrozenValue::HeapPtr {
heap_id,
offset,
is_str,
} => {
TAG_HEAP_PTR.pagable_serialize(serializer)?;
heap_id.pagable_serialize(serializer)?;
offset.pagable_serialize(serializer)?;
is_str.pagable_serialize(serializer)?;
}
SerializedFrozenValue::InlineInt(v) => {
TAG_INLINE_INT.pagable_serialize(serializer)?;
v.pagable_serialize(serializer)?;
}
SerializedFrozenValue::Static(id) => {
TAG_STATIC.pagable_serialize(serializer)?;
id.pagable_serialize(serializer)?;
}
}
Ok(())
}
}
impl<'de> PagableDeserialize<'de> for SerializedFrozenValue {
fn pagable_deserialize<D: PagableDeserializer<'de> + ?Sized>(
deserializer: &mut D,
) -> pagable::Result<Self> {
let tag = u8::pagable_deserialize(deserializer)?;
match tag {
TAG_HEAP_PTR => {
let heap_id = HeapRefId::pagable_deserialize(deserializer)?;
let offset = ArenaOffset::pagable_deserialize(deserializer)?;
let is_str = bool::pagable_deserialize(deserializer)?;
Ok(SerializedFrozenValue::HeapPtr {
heap_id,
offset,
is_str,
})
}
TAG_INLINE_INT => {
let v = i32::pagable_deserialize(deserializer)?;
Ok(SerializedFrozenValue::InlineInt(v))
}
TAG_STATIC => {
let id = StaticValueId::pagable_deserialize(deserializer)?;
Ok(SerializedFrozenValue::Static(id))
}
_ => Err(anyhow::anyhow!(
"Invalid SerializedFrozenValue tag: {}",
tag
)),
}
}
}