Closed Angelo13C closed 1 year ago
Your code has a lot of mistakes unrelated to Ok
so it's tough to tell what you are doing, but I am very confident that using erased_serde's Ok
type is not the right way.
Possibly something like this.
struct Foo {
ty: unsafe fn(*const u8) -> *const dyn erased_serde::Serialize,
}
impl Foo {
fn new<T>() -> Self
where
T: serde::Serialize + 'static,
{
unsafe fn ty<T>(ptr: *const u8) -> *const dyn erased_serde::Serialize
where
T: serde::Serialize + 'static,
{
ptr.cast::<T>()
}
Foo { ty: ty::<T> }
}
unsafe fn serialize<S>(&self, serializer: S, ptr: *const u8) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let value = unsafe { &*(self.ty)(ptr) };
erased_serde::serialize(value, serializer)
}
}
fn main() {
let foo = Foo::new::<i32>();
let ser = serde_json::value::Serializer;
let ptr = &99i32 as *const i32 as *const u8;
let result = unsafe { foo.serialize(ser, ptr) };
println!("{}", result.unwrap());
}
@dtolnay is it possible to erase generic serializer without exporting Ok
?
Because returing Serialize
only works if you serialize the whole value or one of its field. If I need to serialize 2+ fields and now the whole struct, I can't return Serialize
, I need to accept Serializer
in my function.
As you can see from the code below, I only have access to the type that needs to be serialized when I create a new instance of new, so I need to store the serialize_fn:: inside the struct to call it later on.
The problem is that I can't do that because erased_serde::Ok (as you can read from the code) is private in the erased-serde crate.
Can you please make it public (since it's the struct is obtainable in public API as you can see with my code, but it becomes unusable since it's private)?
Thanks :D