Serdeデシリアライザ、 `u8`を直接デコードする際の明確な動作と、` Vec <u8> `での` u8`の方法

2020-05-22 rust serde

私はすでに存在するフォーマットのDeserializerを書いていますが、フォーマットにはserdeで実装する方法がわからない1つの特徴があります:

// pseudo code
fn example(){
   // when decoding an u8 directly, the value 0x00 is invalid
   assert!(<u8>::deserialize(Format::from_bytes(&[0x00u8])).is_err());

   // however, when decoding an u8 through a Vec<u8> 0x00 is valid
   //
   // The problem is that this will first call `deserialize_seq`, which
   // will then use the same function as `<u8>::deserialize`, but I need
   // it to call a different method which actually accepts the value 0x00
   assert_eq!(<Vec<u8>>::deserialize(Format::from_bytes(&[0x00u8])), vec![0x00]);
}

問題は、元の実装が一般的ではなく、値0x00を拒否する u8実装と、 それを受け入れる Vec<u8> あることです。

これをserdeデシリアライザ内で複製するには、何らかのランタイムタイプ情報が必要なようですが、これを実装する方法はありますか?

Answers

ポインタをありがとう@kmdreko、それは非常に役に立ちました。

したがって、私が抱えていた問題は、 Vec<T>に対するserde::de::Deserializeデフォルトの動作Tパラメーター化されたビジターを作成し、 Vec<u8> アイテムが Vec<u8>と同じ非直列化関数を使用することを強制することu8 。 serdeはVec<T>デフォルト実装を提供し、rustはオーバーロードをサポートせず、 特殊化も上陸していないimpl<'de> Deserialize<'de> for Vec<u8>単純にimpl<'de> Deserialize<'de> for Vec<u8>実行することはできませんでした。回避策は、私が名前のユニット構造体、導入したDirectBytes 、そしてコードA impl<'de> Deserialize<'de> for DirectBytesの用途はdeserialize_byte_bufの代わりにdeserialize_seq

serde_bytesは少し複雑で、これらの「プロキシ」構造体があるだけでなく、 Deserializeという独自の特性も持っています。これは、マクロ#[serde(with="..")]が適切に機能するために必要だと思います。また、 deserialize_byte_bufが必要な処理を実行しなかった場合に、この動作を実装する方法もわかりませんが、私の問題としては、ラッピングタイプで十分です。

Related