Я пытаюсь выполнить сериализацию структуры, в которой байты в конечном итоге будут отправляться по каналу, реконструированы и методы будут вызваны на них.Как десериализовать в черту, а не конкретный тип?
Я создал черту эти Структуры будут реализовывать по мере необходимости, и я использую serde и serde-cbor для сериализации:
extern crate serde_cbor;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use serde_cbor::ser::*;
use serde_cbor::de::*;
trait Contract {
fn do_something(&self);
}
#[derive(Debug, Serialize, Deserialize)]
struct Foo {
x: u32,
y: u32,
}
#[derive(Debug, Serialize, Deserialize)]
struct Bar {
data: Vec<Foo>,
}
#[derive(Debug, Serialize, Deserialize)]
struct Baz {
data: Vec<Foo>,
tag: String,
}
impl Contract for Bar {
fn do_something(&self) {
println!("I'm a Bar and this is my data {:?}", self.data);
}
}
impl Contract for Baz {
fn do_something(&self) {
println!("I'm Baz {} and this is my data {:?}", self.tag, self.data);
}
}
fn main() {
let data = Bar { data: vec![Foo { x: 1, y: 2 }, Foo { x: 3, y: 4 }, Foo { x: 7, y: 8 }] };
data.do_something();
let value = to_vec(&data).unwrap();
let res: Result<Contract, _> = from_reader(&value[..]);
let res = res.unwrap();
println!("{:?}", res);
res.do_something();
}
Когда я пытаюсь восстановить байты с помощью признака в качестве типа (при условии, что Я не знаю, какие основной объект отсылается), компилятор жалуется, что черта не реализует Sized
черты:
error[E0277]: the trait bound `Contract: std::marker::Sized` is not satisfied --> src/main.rs:52:15 | 52 | let res: Result<Contract, _> = from_reader(&value[..]); | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Sized` is not implemented for `Contract` | = note: `Contract` does not have a constant size known at compile-time = note: required by `std::result::Result`
Я предполагаю, что это имеет смысл, поскольку компилятор не знает, насколько велика структура, и не знает, как выстроить байты для нее. Если бы я изменить строку, где я десериализацию объекта, чтобы определить фактический тип структуры, он работает:
let res: Result<Bar, _> = from_reader(&value[..]);
Есть ли лучший шаблон для достижения этой сериализации + полиморфизм поведения?
Я ... не думаю, что вы можете сделать это. Вы не можете восстановить структуру, если не знаете ее конкретного типа, и вы не можете вызывать методы на ней, если у вас нет указателя на ее таблицу vtable, которую вы не можете найти, если у вас нет доступа к ее конкретному типу. Можете ли вы сериализовать vtable? – trentcl
Кажется, это так, но я надеялся, что кто-то укажет на то, что мне не хватает. У меня есть неидиоматическое решение для этого, но добавляет связь с кодом ... поэтому я ищу что-то лучшее. – Dash83
Вы уверены, что хотите полиморфизм, а не просто перечисление? Вам нужен ваш код для работы с пользовательскими типами? –