0

クレートを使用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

最初の印刷は正しいですが、上記で説明した逆シリアル化を実装する方法がわかりません。

4

0 に答える 0