mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-14 03:07:57 +01:00
Serde part works now
This commit is contained in:
parent
8d7a4ac5be
commit
f2679a3408
10
src/lib.rs
10
src/lib.rs
@ -19,7 +19,9 @@ mod space;
|
|||||||
|
|
||||||
use crate::oid::ObjectIdentifier;
|
use crate::oid::ObjectIdentifier;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use crate::state::value::{UInt32, Vec3u8, SerializeValue};
|
use crate::state::value::{UInt32, Vec3u8, SerializeDynOid};
|
||||||
|
use rkyv::ser::serializers::AllocSerializer;
|
||||||
|
use rkyv::SerializeUnsized;
|
||||||
|
|
||||||
mod resource;
|
mod resource;
|
||||||
mod schema;
|
mod schema;
|
||||||
@ -76,6 +78,12 @@ pub fn main() {
|
|||||||
println!("{}", &s);
|
println!("{}", &s);
|
||||||
let ent2: state::value::OwnedEntry = serde_json::from_str(&s).unwrap();
|
let ent2: state::value::OwnedEntry = serde_json::from_str(&s).unwrap();
|
||||||
println!("ent2: {:?}", ent2);
|
println!("ent2: {:?}", ent2);
|
||||||
|
|
||||||
|
let mut ser = AllocSerializer::<1024>::default();
|
||||||
|
let b3 = Box::new(true) as Box<dyn state::value::SerializeValue>;
|
||||||
|
let pos = b3.serialize_unsized(&mut ser).unwrap();
|
||||||
|
let buf = ser.into_serializer().into_inner();
|
||||||
|
println!("Serialized {} bytes: {:?}", pos, buf.as_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fn main() {
|
/*fn main() {
|
||||||
|
@ -9,33 +9,43 @@ use std::{
|
|||||||
convert::TryFrom,
|
convert::TryFrom,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rkyv::{Archive, Archived, Serialize, Deserialize, out_field, };
|
use rkyv::{Archive, Archived, Serialize, Deserialize, out_field, Fallible, DeserializeUnsized, ArchivePointee, ArchiveUnsized, ArchivedMetadata, SerializeUnsized};
|
||||||
use rkyv_dyn::{archive_dyn, DynSerializer, DynError, DynDeserializer};
|
use rkyv_dyn::{archive_dyn, DynSerializer, DynError, DynDeserializer};
|
||||||
use rkyv_typename::TypeName;
|
use rkyv_typename::TypeName;
|
||||||
use ptr_meta::{DynMetadata, Pointee};
|
use ptr_meta::{DynMetadata, Pointee};
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
use inventory;
|
use inventory;
|
||||||
use crate::oid::{ObjectIdentifier};
|
use crate::oid::{ObjectIdentifier};
|
||||||
use rkyv::ser::{Serializer, };
|
use rkyv::ser::{Serializer, ScratchSpace};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use serde::ser::SerializeMap;
|
use serde::ser::SerializeMap;
|
||||||
use std::fmt::Formatter;
|
use std::fmt::Formatter;
|
||||||
use serde::de::Error as _;
|
use serde::de::Error as _;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
|
|
||||||
pub trait Value: fmt::Debug + erased_serde::Serialize {
|
pub trait Value: fmt::Debug + erased_serde::Serialize {
|
||||||
fn deserialize_val_in_place<'de>(&mut self, deserializer: &mut dyn erased_serde::Deserializer<'de>)
|
/// Initialize `&mut self` from `deserializer`
|
||||||
-> Result<(), erased_serde::Error>;
|
///
|
||||||
|
/// At the point this is called &mut self is of undefined value but guaranteed to be well
|
||||||
|
/// aligned and non-null. Any read access into &mut self before all of &self is brought into
|
||||||
|
/// a valid state is however undefined behaviour.
|
||||||
|
/// To this end you *must* initialize `self` **completely**. Serde will do the right thing if
|
||||||
|
/// you directly deserialize the type you're implementing `Value` for, but for manual
|
||||||
|
/// implementations this is important to keep in mind.
|
||||||
|
fn deserialize_init<'de>(&mut self, deserializer: &mut dyn erased_serde::Deserializer<'de>)
|
||||||
|
-> Result<(), erased_serde::Error>;
|
||||||
}
|
}
|
||||||
erased_serde::serialize_trait_object!(Value);
|
erased_serde::serialize_trait_object!(Value);
|
||||||
|
|
||||||
impl<T> Value for T
|
impl<T> Value for T
|
||||||
where T: fmt::Debug + Archive + erased_serde::Serialize + for<'de> serde::Deserialize<'de>
|
where T: fmt::Debug
|
||||||
|
+ erased_serde::Serialize
|
||||||
|
+ for<'de> serde::Deserialize<'de>
|
||||||
{
|
{
|
||||||
fn deserialize_val_in_place<'de>(&mut self, deserializer: &mut dyn erased_serde::Deserializer<'de>)
|
fn deserialize_init<'de>(&mut self, deserializer: &mut dyn erased_serde::Deserializer<'de>)
|
||||||
-> Result<(), erased_serde::Error>
|
-> Result<(), erased_serde::Error>
|
||||||
{
|
{
|
||||||
*self = erased_serde::deserialize(deserializer)?;
|
*self = erased_serde::deserialize(deserializer)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -51,10 +61,11 @@ pub struct Entry<'a> {
|
|||||||
pub oid: &'a ObjectIdentifier,
|
pub oid: &'a ObjectIdentifier,
|
||||||
pub val: &'a dyn Value,
|
pub val: &'a dyn Value,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OwnedEntry {
|
pub struct OwnedEntry {
|
||||||
pub oid: ObjectIdentifier,
|
pub oid: ObjectIdentifier,
|
||||||
pub val: Box<dyn Value>,
|
pub val: Box<dyn DeserializeValue>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> serde::Serialize for Entry<'a> {
|
impl<'a> serde::Serialize for Entry<'a> {
|
||||||
@ -74,7 +85,9 @@ impl<'de> serde::Deserialize<'de> for OwnedEntry {
|
|||||||
deserializer.deserialize_map(OwnedEntryVisitor)
|
deserializer.deserialize_map(OwnedEntryVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OwnedEntryVisitor;
|
struct OwnedEntryVisitor;
|
||||||
|
|
||||||
impl<'de> serde::de::Visitor<'de> for OwnedEntryVisitor {
|
impl<'de> serde::de::Visitor<'de> for OwnedEntryVisitor {
|
||||||
type Value = OwnedEntry;
|
type Value = OwnedEntry;
|
||||||
|
|
||||||
@ -97,13 +110,15 @@ impl<'de> serde::de::Visitor<'de> for OwnedEntryVisitor {
|
|||||||
let valimpl = IMPL_REGISTRY.get(ImplId::from_type_oid(&b))
|
let valimpl = IMPL_REGISTRY.get(ImplId::from_type_oid(&b))
|
||||||
.ok_or(serde::de::Error::invalid_value(
|
.ok_or(serde::de::Error::invalid_value(
|
||||||
serde::de::Unexpected::Other("unknown oid"),
|
serde::de::Unexpected::Other("unknown oid"),
|
||||||
&"oid an implementation was registered for"
|
&"oid an implementation was registered for",
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
// Casting random usize you find on the side of the road as vtable on unchecked pointers.
|
// Casting random usize you find on the side of the road as vtable on unchecked pointers.
|
||||||
// What could possibly go wrong? >:D
|
// What could possibly go wrong? >:D
|
||||||
let valbox: Box<dyn Value> = unsafe {
|
let valbox: MaybeUninit<Box<dyn DeserializeValue>> = unsafe {
|
||||||
// recreate vtable as fat ptr metadata
|
// "recreate" vtable as fat ptr metadata (we literally just cast an `usize` but the
|
||||||
|
// only way to put this usize into that spot is by having a valid vtable cast so it's
|
||||||
|
// probably almost safe)
|
||||||
let meta = valimpl.pointer_metadata();
|
let meta = valimpl.pointer_metadata();
|
||||||
|
|
||||||
// Don't bother checking here. The only way this could be bad is if the vtable above
|
// Don't bother checking here. The only way this could be bad is if the vtable above
|
||||||
@ -116,29 +131,42 @@ impl<'de> serde::de::Visitor<'de> for OwnedEntryVisitor {
|
|||||||
// validate in any other way if this is sane?
|
// validate in any other way if this is sane?
|
||||||
// Well...
|
// Well...
|
||||||
let ptr: *mut () = std::alloc::alloc(layout).cast::<()>();
|
let ptr: *mut () = std::alloc::alloc(layout).cast::<()>();
|
||||||
Box::from_raw(ptr_meta::from_raw_parts_mut(ptr, meta))
|
let b = Box::from_raw(ptr_meta::from_raw_parts_mut(
|
||||||
|
ptr,
|
||||||
|
meta));
|
||||||
|
|
||||||
|
// We make this a MaybeUninit so `Drop` is never called on the uninitialized value
|
||||||
|
MaybeUninit::new(b)
|
||||||
};
|
};
|
||||||
// ... The only way we can make Value a trait object by having it deserialize *into
|
// ... The only way we can make Value a trait object by having it deserialize *into
|
||||||
// it's own uninitialized representation*. Yeah don't worry, this isn't the worst part of
|
// it's own uninitialized representation*. Yeah don't worry, this isn't the worst part of
|
||||||
// the game yet. >:D
|
// the game yet. >:D
|
||||||
let seed = ValueSeed(valbox);
|
let seed = InitIntoSelf(valbox);
|
||||||
let val = map.next_value_seed(seed)?;
|
let val = map.next_value_seed(seed)?;
|
||||||
Ok(OwnedEntry { oid, val })
|
Ok(OwnedEntry { oid, val })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct ValueSeed(Box<dyn Value>);
|
|
||||||
impl<'de> serde::de::DeserializeSeed<'de> for ValueSeed {
|
struct InitIntoSelf(MaybeUninit<Box<dyn DeserializeValue>>);
|
||||||
type Value = Box<dyn Value>;
|
|
||||||
|
impl<'de> serde::de::DeserializeSeed<'de> for InitIntoSelf {
|
||||||
|
type Value = Box<dyn DeserializeValue>;
|
||||||
|
|
||||||
fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>
|
fn deserialize<D>(mut self, deserializer: D) -> Result<Self::Value, D::Error>
|
||||||
where D: serde::Deserializer<'de>
|
where D: serde::Deserializer<'de>
|
||||||
{
|
{
|
||||||
let mut deser = <dyn erased_serde::Deserializer>::erase(deserializer);
|
let mut deser = <dyn erased_serde::Deserializer>::erase(deserializer);
|
||||||
// Hey, better initialize late than never. Oh completely unrelated but if we unwind after
|
|
||||||
// allocating the box and before completing this function call that's undefined behaviour
|
// Unsafe as hell but if we never read from this reference before initializing it's not
|
||||||
// so maybe don't do that thanks <3
|
// undefined behaviour.
|
||||||
self.0.deserialize_val_in_place(&mut deser);
|
let selfptr = unsafe { &mut *self.0.as_mut_ptr() };
|
||||||
Ok(self.0)
|
|
||||||
|
// Hey, better initialize late than never.
|
||||||
|
selfptr.deserialize_init(&mut deser).map_err(|e|
|
||||||
|
D::Error::custom(e))?;
|
||||||
|
|
||||||
|
// Assuming `deserialize_init` didn't error and did its job this is now safe.
|
||||||
|
unsafe { Ok(self.0.assume_init()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,17 +179,46 @@ impl TypeOid for Archived<bool> {
|
|||||||
ObjectIdentifier::try_from("1.3.6.1.4.1.48398.612.1.1").unwrap()
|
ObjectIdentifier::try_from("1.3.6.1.4.1.48398.612.1.1").unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl DeserializeDynOid for Archived<bool>
|
||||||
|
where Archived<bool>: for<'a> Deserialize<bool, (dyn DynDeserializer + 'a)>
|
||||||
|
{
|
||||||
|
unsafe fn deserialize_dynoid(&self, deserializer: &mut dyn DynDeserializer, alloc: &mut dyn FnMut(Layout) -> *mut u8) -> Result<*mut (), DynError> {
|
||||||
|
let ptr = alloc(Layout::new::<bool>()).cast::<bool>();
|
||||||
|
ptr.write(self.deserialize(deserializer)?);
|
||||||
|
Ok(ptr as *mut ())
|
||||||
|
}
|
||||||
|
|
||||||
pub trait SerializeValue {
|
fn deserialize_dynoid_metadata(&self, deserializer: &mut dyn DynDeserializer) -> Result<<dyn SerializeValue as Pointee>::Metadata, DynError> {
|
||||||
fn serialize_val(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError>;
|
unsafe {
|
||||||
|
Ok(core::mem::transmute(ptr_meta::metadata(
|
||||||
|
core::ptr::null::<bool>() as *const dyn SerializeValue
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<S: ScratchSpace + Serializer + ?Sized> SerializeUnsized<S> for dyn SerializeValue {
|
||||||
|
fn serialize_unsized(&self, mut serializer: &mut S) -> Result<usize, S::Error> {
|
||||||
|
self.serialize_dynoid(&mut serializer)
|
||||||
|
.map_err(|e| *e.downcast::<S::Error>().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_metadata(&self, mut serializer: &mut S) -> Result<Self::MetadataResolver, S::Error> {
|
||||||
|
self.serialize_metadata(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Serialize dynamic types by storing an OID alongside
|
||||||
|
pub trait SerializeDynOid {
|
||||||
|
fn serialize_dynoid(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError>;
|
||||||
fn archived_type_oid(&self) -> ObjectIdentifier;
|
fn archived_type_oid(&self) -> ObjectIdentifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SerializeValue for T
|
impl<T> SerializeDynOid for T
|
||||||
where T: for<'a> Serialize<dyn DynSerializer + 'a>,
|
where T: for<'a> Serialize<dyn DynSerializer + 'a>,
|
||||||
T::Archived: TypeOid,
|
T::Archived: TypeOid,
|
||||||
{
|
{
|
||||||
fn serialize_val(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError> {
|
fn serialize_dynoid(&self, serializer: &mut dyn DynSerializer) -> Result<usize, DynError> {
|
||||||
serializer.serialize_value(self)
|
serializer.serialize_value(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,37 +227,81 @@ impl<T> SerializeValue for T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait DeserializeValue<T: Pointee + ?Sized> {
|
trait DeserializeDynOid {
|
||||||
unsafe fn deserialize_val(
|
unsafe fn deserialize_dynoid(
|
||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn DynDeserializer,
|
deserializer: &mut dyn DynDeserializer,
|
||||||
alloc: &mut dyn FnMut(Layout) -> *mut u8,
|
alloc: &mut dyn FnMut(Layout) -> *mut u8,
|
||||||
) -> Result<*mut (), DynError>;
|
) -> Result<*mut (), DynError>;
|
||||||
|
|
||||||
fn deserialize_dyn_metadata(
|
fn deserialize_dynoid_metadata(
|
||||||
&self,
|
&self,
|
||||||
deserializer: &mut dyn DynDeserializer,
|
deserializer: &mut dyn DynDeserializer,
|
||||||
) -> Result<T::Metadata, DynError>;
|
) -> Result<<dyn SerializeValue as Pointee>::Metadata, DynError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ArchivedValueMetadata<T: ?Sized> {
|
#[ptr_meta::pointee]
|
||||||
|
pub trait SerializeValue: Value + SerializeDynOid {}
|
||||||
|
|
||||||
|
impl<T: Archive + SerializeDynOid + Value> SerializeValue for T
|
||||||
|
where
|
||||||
|
T::Archived: RegisteredImpl
|
||||||
|
{}
|
||||||
|
|
||||||
|
#[ptr_meta::pointee]
|
||||||
|
pub trait DeserializeValue: Value + DeserializeDynOid {}
|
||||||
|
impl<T: Value + DeserializeDynOid> DeserializeValue for T {}
|
||||||
|
impl ArchivePointee for dyn DeserializeValue {
|
||||||
|
type ArchivedMetadata = ArchivedValueMetadata;
|
||||||
|
|
||||||
|
fn pointer_metadata(archived: &Self::ArchivedMetadata) -> <Self as Pointee>::Metadata {
|
||||||
|
archived.pointer_metadata()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<D: ?Sized> DeserializeUnsized<dyn SerializeValue, D> for dyn DeserializeValue
|
||||||
|
where D: Fallible + DynDeserializer
|
||||||
|
{
|
||||||
|
unsafe fn deserialize_unsized(&self,
|
||||||
|
mut deserializer: &mut D,
|
||||||
|
mut alloc: impl FnMut(Layout) -> *mut u8
|
||||||
|
) -> Result<*mut (), D::Error> {
|
||||||
|
self.deserialize_dynoid(&mut deserializer, &mut alloc).map_err(|e| *e.downcast().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize_metadata(&self, mut deserializer: &mut D)
|
||||||
|
-> Result<<dyn SerializeValue as Pointee>::Metadata, D::Error>
|
||||||
|
{
|
||||||
|
self.deserialize_dynoid_metadata(&mut deserializer).map_err(|e| *e.downcast().unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArchiveUnsized for dyn SerializeValue {
|
||||||
|
type Archived = dyn DeserializeValue;
|
||||||
|
type MetadataResolver = <ObjectIdentifier as Archive>::Resolver;
|
||||||
|
|
||||||
|
unsafe fn resolve_metadata(&self, pos: usize, resolver: Self::MetadataResolver, out: *mut ArchivedMetadata<Self>) {
|
||||||
|
let (oid_pos, oid) = out_field!(out.type_oid);
|
||||||
|
let type_oid = self.archived_type_oid();
|
||||||
|
type_oid.resolve(oid_pos, resolver, oid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ArchivedValueMetadata {
|
||||||
type_oid: Archived<ObjectIdentifier>,
|
type_oid: Archived<ObjectIdentifier>,
|
||||||
phantom: PhantomData<T>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: TypeOid + ?Sized> ArchivedValueMetadata<T> {
|
impl ArchivedValueMetadata {
|
||||||
pub unsafe fn emplace(type_oid: Archived<ObjectIdentifier>, out: *mut Self) {
|
pub unsafe fn emplace(type_oid: Archived<ObjectIdentifier>, out: *mut Self) {
|
||||||
ptr::addr_of_mut!((*out).type_oid).write(type_oid);
|
ptr::addr_of_mut!((*out).type_oid).write(type_oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vtable(&self) -> usize {
|
pub fn vtable(&self) -> usize {
|
||||||
IMPL_REGISTRY
|
IMPL_REGISTRY
|
||||||
.get(ImplId::from_type_oid(&self.type_oid))
|
.get(ImplId::from_type_oid(&self.type_oid)).expect("Unregistered type oid")
|
||||||
.expect("Unregistered type oid")
|
|
||||||
.vtable
|
.vtable
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pointer_metadata(&self) -> DynMetadata<T> {
|
pub fn pointer_metadata(&self) -> DynMetadata<dyn DeserializeValue> {
|
||||||
unsafe { core::mem::transmute(self.vtable()) }
|
unsafe { core::mem::transmute(self.vtable()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,6 +316,7 @@ impl<'a> ImplId<'a> {
|
|||||||
Self { type_oid }
|
Self { type_oid }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImplId<'static> {
|
impl ImplId<'static> {
|
||||||
fn new<T: TypeOid>() -> Self {
|
fn new<T: TypeOid>() -> Self {
|
||||||
let oid: Vec<u8> = T::get_type_oid().into();
|
let oid: Vec<u8> = T::get_type_oid().into();
|
||||||
@ -230,6 +332,7 @@ struct ImplData {
|
|||||||
// TODO DebugImpl
|
// TODO DebugImpl
|
||||||
// TODO DebugInfo
|
// TODO DebugInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImplData {
|
impl ImplData {
|
||||||
pub unsafe fn pointer_metadata<T: ?Sized>(&self) -> DynMetadata<T> {
|
pub unsafe fn pointer_metadata<T: ?Sized>(&self) -> DynMetadata<T> {
|
||||||
core::mem::transmute(self.vtable)
|
core::mem::transmute(self.vtable)
|
||||||
@ -292,7 +395,7 @@ unsafe impl RegisteredImpl for bool {
|
|||||||
fn vtable() -> usize {
|
fn vtable() -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
core::mem::transmute(ptr_meta::metadata(
|
core::mem::transmute(ptr_meta::metadata(
|
||||||
core::ptr::null::<bool>() as *const dyn Value
|
core::ptr::null::<bool>() as *const dyn DeserializeValue
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,5 +486,4 @@ impl DynValue for Vec3u8 {}
|
|||||||
impl DynValue for Archived<Vec3u8> {}
|
impl DynValue for Archived<Vec3u8> {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {}
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user