serde_gff/de/
value.rs

1//! Содержит реализацию типажа `Deserialize` для десериализации типа `Value`
2
3use std::collections::HashMap;
4use std::fmt;
5use std::marker::PhantomData;
6use indexmap::IndexMap;
7use serde::forward_to_deserialize_any;
8use serde::de::{Deserialize, Deserializer, Error, IntoDeserializer, SeqAccess, MapAccess, Visitor};
9
10use crate::Label;
11use crate::string::{GffString, StringKey};
12use crate::value::Value;
13
14macro_rules! string_key {
15  ($method:ident, $type:ty) => (
16    #[inline]
17    fn $method<E>(self, value: $type) -> Result<Key, E>
18      where E: Error,
19    {
20      Ok(Key::String(StringKey(value as u32)))
21    }
22  );
23}
24/// Возможные представления ключа отображений в форматах данных
25enum Key {
26  /// Ключ отображения является строкой, символом или массивом байт и соответствует
27  /// метке поля
28  Label(Label),
29  /// Ключ отображения является числом и соответствует элементу многоязыковой строки
30  String(StringKey),
31}
32/// Структура для конвертации событий десериализации от serde в объект `Key`
33struct KeyVisitor;
34
35impl<'de> Visitor<'de> for KeyVisitor {
36  type Value = Key;
37
38  fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
39    formatter.write_str("a string with length in UTF-8 <=16, byte buffer with length <=16, char or integer")
40  }
41
42  string_key!(visit_u8, u8);
43  string_key!(visit_i8, i8);
44  string_key!(visit_u16, u16);
45  string_key!(visit_i16, i16);
46  string_key!(visit_u32, u32);
47  string_key!(visit_i32, i32);
48  string_key!(visit_u64, u64);
49  string_key!(visit_i64, i64);
50  string_key!(visit_u128, u128);
51  string_key!(visit_i128, i128);
52
53  #[inline]
54  fn visit_char<E>(self, value: char) -> Result<Key, E>
55    where E: Error,
56  {
57    self.visit_string(value.to_string())
58  }
59  #[inline]
60  fn visit_str<E>(self, value: &str) -> Result<Key, E>
61    where E: Error,
62  {
63    self.visit_bytes(value.as_bytes())
64  }
65
66  #[inline]
67  fn visit_bytes<E>(self, value: &[u8]) -> Result<Key, E>
68    where E: Error,
69  {
70    use crate::error::Error::TooLongLabel;
71
72    match Label::from_bytes(value) {
73      Ok(label) => Ok(Key::Label(label)),
74      Err(TooLongLabel(len)) => Err(E::invalid_length(len, &self)),
75      Err(err) => Err(E::custom(err)),// На самом деле, этот вариант невозможен
76    }
77  }
78}
79
80/// Десериализует метку из строки или массива байт
81impl<'de> Deserialize<'de> for Key {
82  #[inline]
83  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
84    where D: Deserializer<'de>,
85  {
86    deserializer.deserialize_any(KeyVisitor)
87  }
88}
89
90///////////////////////////////////////////////////////////////////////////////////////////////////
91
92/// Структура для конвертации событий десериализации от serde в объект `Label`
93struct LabelVisitor;
94
95impl<'de> Visitor<'de> for LabelVisitor {
96  type Value = Label;
97
98  fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
99    formatter.write_str("a string with length in UTF-8 <=16, byte buffer with length <=16, or char")
100  }
101
102  #[inline]
103  fn visit_char<E>(self, value: char) -> Result<Label, E>
104    where E: Error,
105  {
106    self.visit_string(value.to_string())
107  }
108  #[inline]
109  fn visit_str<E>(self, value: &str) -> Result<Label, E>
110    where E: Error,
111  {
112    self.visit_bytes(value.as_bytes())
113  }
114
115  #[inline]
116  fn visit_bytes<E>(self, value: &[u8]) -> Result<Label, E>
117    where E: Error,
118  {
119    use crate::error::Error::TooLongLabel;
120
121    match Label::from_bytes(value) {
122      Ok(label) => Ok(label),
123      Err(TooLongLabel(len)) => Err(E::invalid_length(len, &self)),
124      Err(err) => Err(E::custom(err)),// На самом деле, этот вариант невозможен
125    }
126  }
127}
128
129/// Десериализует метку из строки или массива байт
130impl<'de> Deserialize<'de> for Label {
131  #[inline]
132  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
133    where D: Deserializer<'de>,
134  {
135    deserializer.deserialize_any(LabelVisitor)
136  }
137}
138
139/// Десериализатор, в котором источником данных является метка
140#[derive(Debug)]
141pub struct LabelDeserializer<E> {
142  /// Источник данных, из которого достаются данные для десериализации других структур
143  value: Label,
144  /// Фиктивный элемент, для связывания типа ошибки `E`
145  marker: PhantomData<E>,
146}
147impl<'de, E> IntoDeserializer<'de, E> for Label
148  where E: Error,
149{
150  type Deserializer = LabelDeserializer<E>;
151
152  #[inline]
153  fn into_deserializer(self) -> Self::Deserializer {
154    LabelDeserializer { value: self, marker: PhantomData }
155  }
156}
157impl<'de, E> Deserializer<'de> for LabelDeserializer<E>
158  where E: Error,
159{
160  type Error = E;
161
162  fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
163    where V: Visitor<'de>,
164  {
165    if let Ok(str) = self.value.as_str() {
166      return visitor.visit_str(str);
167    }
168    visitor.visit_bytes(self.value.as_ref())
169  }
170
171  forward_to_deserialize_any!(
172    bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
173    string bytes byte_buf option unit unit_struct newtype_struct seq
174    tuple tuple_struct map struct enum identifier ignored_any
175  );
176}
177
178///////////////////////////////////////////////////////////////////////////////////////////////////
179
180/// Макрос, создающий функцию конвертации события serde в один из вариантов GFF значения
181macro_rules! value_from_primitive {
182  ($name:ident, $type:ty => $variant:ident) => (
183    #[inline]
184    fn $name<E>(self, value: $type) -> Result<Value, E> {
185      Ok(Value::$variant(value.into()))
186    }
187  );
188}
189
190/// Структура для конвертации событий десериализации от serde в объект `Value`
191struct ValueVisitor;
192
193impl<'de> Visitor<'de> for ValueVisitor {
194  type Value = Value;
195
196  fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
197    formatter.write_str("any valid GFF value")
198  }
199
200  #[inline]
201  fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
202    Ok(Value::Byte(if value { 1 } else { 0 }))
203  }
204
205  value_from_primitive!(visit_i8 , i8  => Char);
206  value_from_primitive!(visit_i16, i16 => Short);
207  value_from_primitive!(visit_i32, i32 => Int);
208  value_from_primitive!(visit_i64, i64 => Int64);
209  //visit_i128 - не поддерживается
210
211  value_from_primitive!(visit_u8 , u8  => Byte);
212  value_from_primitive!(visit_u16, u16 => Word);
213  value_from_primitive!(visit_u32, u32 => Dword);
214  value_from_primitive!(visit_u64, u64 => Dword64);
215  //visit_u128 - не поддерживается
216
217  value_from_primitive!(visit_f32, f32 => Float);
218  value_from_primitive!(visit_f64, f64 => Double);
219
220  //visit_char - не поддерживается
221
222  value_from_primitive!(visit_str, &str => String);
223  //visit_borrowed_str - устраивает реализация по умолчанию
224  value_from_primitive!(visit_string, String => String);
225
226  value_from_primitive!(visit_bytes, &[u8] => Void);
227  //visit_borrowed_bytes - устраивает реализация по умолчанию
228  value_from_primitive!(visit_byte_buf, Vec<u8> => Void);
229
230  //visit_none - не поддерживается
231  #[inline]
232  fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
233    where D: Deserializer<'de>,
234  {
235    Deserialize::deserialize(deserializer)
236  }
237
238  #[inline]
239  fn visit_unit<E>(self) -> Result<Value, E> {
240    Ok(Value::Struct(IndexMap::with_capacity(0)))
241  }
242  //visit_newtype_struct - не поддерживается
243
244  #[inline]
245  fn visit_seq<V>(self, mut seq: V) -> Result<Value, V::Error>
246    where V: SeqAccess<'de>,
247  {
248    let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
249
250    while let Some(elem) = seq.next_element()? {
251      vec.push(elem);
252    }
253
254    Ok(Value::List(vec))
255  }
256  fn visit_map<V>(self, mut map: V) -> Result<Value, V::Error>
257    where V: MapAccess<'de>,
258  {
259    let size = map.size_hint().unwrap_or(0);
260
261    if let Some(key) = map.next_key()? {
262      match key {
263        Key::Label(label) => {
264          let mut values = IndexMap::with_capacity(size);
265          values.insert(label, map.next_value()?);
266
267          while let Some((key, value)) = map.next_entry()? {
268            values.insert(key, value);
269          }
270
271          Ok(Value::Struct(values))
272        },
273        Key::String(key) => {
274          let mut values = HashMap::with_capacity(size);
275          values.insert(key, map.next_value()?);
276
277          while let Some((key, value)) = map.next_entry()? {
278            values.insert(StringKey(key), value);
279          }
280
281          Ok(Value::LocString(GffString::Internal(values).into()))
282        },
283      }
284    } else {
285      Ok(Value::Struct(IndexMap::with_capacity(0)))
286    }
287  }
288  //visit_enum - не поддерживается
289}
290
291impl<'de> Deserialize<'de> for Value {
292  #[inline]
293  fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
294    where D: Deserializer<'de>,
295  {
296    deserializer.deserialize_any(ValueVisitor)
297  }
298}
299
300/// Десериализатор, в котором источником данных является GFF значение
301#[derive(Debug)]
302pub struct ValueDeserializer<E> {
303  /// Источник данных, из которого достаются данные для десериализации других структур
304  value: Value,
305  /// Фиктивный элемент, для связывания типа ошибки `E`
306  marker: PhantomData<E>,
307}
308impl<'de, E> IntoDeserializer<'de, E> for Value
309  where E: Error,
310{
311  type Deserializer = ValueDeserializer<E>;
312
313  #[inline]
314  fn into_deserializer(self) -> Self::Deserializer {
315    ValueDeserializer { value: self, marker: PhantomData }
316  }
317}
318impl<'de, E> Deserializer<'de> for ValueDeserializer<E>
319  where E: Error,
320{
321  type Error = E;
322
323  #[inline]
324  fn is_human_readable(&self) -> bool { false }
325
326  fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
327    where V: Visitor<'de>,
328  {
329    use self::Value::*;
330
331    match self.value {
332      Byte(val)      => visitor.visit_u8(val),
333      Char(val)      => visitor.visit_i8(val),
334      Word(val)      => visitor.visit_u16(val),
335      Short(val)     => visitor.visit_i16(val),
336      Dword(val)     => visitor.visit_u32(val),
337      Int(val)       => visitor.visit_i32(val),
338      Dword64(val)   => visitor.visit_u64(val),
339      Int64(val)     => visitor.visit_i64(val),
340      Float(val)     => visitor.visit_f32(val),
341      Double(val)    => visitor.visit_f64(val),
342      String(val)    => visitor.visit_string(val),
343      ResRef(val)    => {
344        if let Ok(str) = val.as_str() {
345          return visitor.visit_str(str);
346        }
347        visitor.visit_byte_buf(val.0)
348      },
349      LocString(val) => {
350        let value: GffString = val.into();
351        value.into_deserializer().deserialize_any(visitor)
352      },
353      Void(val)      => visitor.visit_byte_buf(val),
354      Struct(val)    => {
355        //TODO: После мерджа https://github.com/bluss/indexmap/pull/87 можно заменить на into_deserializer()
356        use serde::de::value::MapDeserializer;
357        MapDeserializer::new(val.into_iter()).deserialize_any(visitor)
358      },
359      List(val)      => val.into_deserializer().deserialize_any(visitor),
360    }
361  }
362
363  forward_to_deserialize_any!(
364    bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
365    string bytes byte_buf option unit unit_struct newtype_struct seq
366    tuple tuple_struct map struct enum identifier ignored_any
367  );
368}