クレートを使用serde
して特定の構造体の高度なシリアライゼーション/デシリアライゼーション スキームを実装しようとしています。bincode
実証するために、次のコードが機能します。
use serde::{Serialize, Deserialize};
use bincode::{DefaultOptions, Options};
#[derive(Debug, Serialize, Deserialize)]
enum Command {
Operation(u8),
Element(Vec<u8>)
}
fn main() {
let commands: Vec<Command> = vec![Command::Operation(150), Command::Operation(175), Command::Element(b"123".to_vec())];
let bytes = DefaultOptions::new()
.with_varint_encoding()
.serialize(&commands).unwrap();
println!("{:?}", bytes);
let commands: Vec<Command> = DefaultOptions::new()
.with_varint_encoding()
.deserialize(&bytes[..]).unwrap();
println!("{:?}", commands);
}
出力:
[3, 0, 150, 0, 175, 1, 3, 49, 50, 51]
[Operation(150), Operation(175), Element([49, 50, 51])]
ただし、データをより圧縮された形式でシリアル化したいと考えています。データに含まれるバリアントを識別する明示的なタグはありません。代わりに、これを対応するバイトから派生させたいと考えています。バイトが 100 未満の場合は Element Vec<u8>
、それ以外の場合は Commandu8
です。私はそのように設定しようとし#[serde(untagged)]
ましたCommand
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum Command {
Operation(u8),
Element(Vec<u8>)
}
次の出力が得られます。
[3, 150, 175, 3, 49, 50, 51]
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: DeserializeAnyNotSupported', src/main.rs:45:46
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
最初の印刷は正しいですが、上記で説明した逆シリアル化を実装する方法がわかりません。