У меня есть такой тип, хотя на самом деле мой тип больше и сложнее:
struct MyType {
i: u32,
}
Если я реализую Deserialize
для этого типа, serde будет искать что-то вроде этого (меня интересует JSON):
{"i":100}
Я хочу настроить его так, чтобы я мог десериализовать также из массива байтов:
[1, 2, 3, 4]
Я могу написать impl для обработки массива, но я хочу, чтобы serde автоматически сгенерировал остальное (что будет visit_map
):
impl<'de> Deserialize<'de> for MyType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct MyTypeVisitor;
impl<'de> Visitor<'de> for MyTypeVisitor {
type Value = MyType;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "struct or array of 4 integers")
}
fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
// ...
}
}
// deserializer.deserialize_any(MyTypeVisitor)
}
}
Это возможно? В этом примере это несложно, но когда структура большая, десериализация от руки может быть болезненной.
Это не дубликат Как преобразовать поля во время десериализации с помощью Serde?, потому что deserialize_with
работает только для 1 поля. Я не могу понять, как бы это работало для моего настоящего типа:
pub enum Component {
String(StringComponent),
Translation(TranslationComponent),
Score(ScoreComponent),
Selector(SelectorComponent),
}
pub struct StringComponent {
#[serde(flatten)] pub base: Base,
pub text: String,
}
pub struct Base {
// ...
extra: Option<Vec<Component>>,
// ...
}
Что я хочу сделать:
- Если при десериализации введено число, верните
Component::String
. Это можно сделать с _10 _ / _ 11 _ / _ 12_ и друзьями. - Если ввод является строкой, снова верните
Component::String
. Это можно сделать с помощью _14 _ / _ 15_. - Если входом является массив
[..]
, десериализуйте его как обычно, но сделайте присвоение элементов в массиве [1 ..] дополнительным элементам массива [0]. Это можно сделать с помощьюvisit_seq
. - Если ввод - это карта, позвольте serde derive обработать ее.