Skip to main content

serde_gff/de/
mod.rs

1//! Десериализатор для формата Bioware GFF (Generic File Format)
2
3use std::io::{Read, Seek};
4use encoding::{DecoderTrap, EncodingRef};
5use serde::de::{self, IntoDeserializer, Visitor, DeserializeSeed};
6
7use crate::value::{SimpleValueRef, Value};
8use crate::error::{Error, Result};
9use crate::parser::{Parser, Token};
10
11mod string;
12mod value;
13
14/// Структура для поддержки чтения GFF файлов в экосистеме serde
15pub struct Deserializer<R: Read + Seek> {
16  /// Итератор, поставляющий токены в процессе разбора файла
17  parser: Parser<R>,
18  /// Подсмотренный вперед на один переход токен
19  peeked: Option<Token>,
20}
21
22impl<R: Read + Seek> Deserializer<R> {
23  /// Создает десериализатор для чтения GFF файла из указанного источника данных с использованием
24  /// кодировки `UTF-8` для декодирования строк и генерацией ошибки в случае, если декодировать
25  /// набор байт, как строку в этой кодировке, не удалось.
26  ///
27  /// # Параметры
28  /// - `reader`: Источник данных для чтения файла
29  ///
30  /// # Ошибки
31  /// В случае, если не удалось прочитать заголовок GFF файла -- например, он слишком короткий
32  pub fn new(reader: R) -> Result<Self> {
33    Ok(Deserializer { parser: Parser::new(reader)?, peeked: None })
34  }
35  /// Создает десериализатор для чтения GFF файла из указанного источника данных с использованием
36  /// указанной кодировки для декодирования строк.
37  ///
38  /// # Параметры
39  /// - `reader`: Источник данных для чтения файла
40  /// - `encoding`: Кодировка для декодирования символов в строках
41  /// - `trap`: Способ обработки символов в строках, которые не удалось декодировать с
42  ///   использованием выбранной кодировки
43  ///
44  /// # Ошибки
45  /// В случае, если не удалось прочитать заголовок GFF файла -- например, он слишком короткий
46  pub fn with_encoding(reader: R, encoding: EncodingRef, trap: DecoderTrap) -> Result<Self> {
47    Ok(Deserializer { parser: Parser::with_encoding(reader, encoding, trap)?, peeked: None })
48  }
49
50  /// Возвращает следующий токен из потока, поглощая его
51  #[inline]
52  fn next_token(&mut self) -> Result<Token> {
53    match self.peeked.take() {
54      Some(v) => Ok(v),
55      None => self.parser.next_token(),
56    }
57  }
58  /// Подсматривает следующий токен в потоке, не поглощая его
59  fn peek_token(&mut self) -> Result<&Token> {
60    if self.peeked.is_none() {
61      self.peeked = Some(self.next_token()?);
62    }
63    match self.peeked {
64      Some(ref value) => Ok(value),
65      _ => unreachable!(),
66    }
67  }
68  /// Десериализует все примитивные типы GFF файла (все типы, кроме структур и списков)
69  fn deserialize_value<'de, V>(&mut self, value: SimpleValueRef, visitor: V) -> Result<V::Value>
70    where V: Visitor<'de>,
71  {
72    use serde::Deserializer;
73
74    let value: Value = self.parser.read_value(value)?.into();
75    value.into_deserializer().deserialize_any(visitor)
76  }
77}
78
79/// Реализует разбор простых типов данных.
80///
81/// # Параметры
82/// - `dser_method`: реализуемый макросом метод
83/// - `visit_method`: метод типажа [`Visitor`], который будет вызван для создания конечного значения
84/// - `type`: тип GFF файла, одно из значений перечисления [`SimpleValueRef`]
85///
86/// [`Visitor`]: https://docs.serde.rs/serde/de/trait.Visitor.html
87/// [`SimpleValueRef`]: ../enum.SimpleValueRef.html
88macro_rules! primitive {
89  ($dser_method:ident, $visit_method:ident, $type:ident) => (
90    fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
91      where V: Visitor<'de>,
92    {
93      let token = self.next_token()?;
94      if let Token::Value(SimpleValueRef::$type(value)) = token {
95        return visitor.$visit_method(value);
96      }
97      return Err(Error::Unexpected(stringify!($type), token));
98    }
99  );
100  ($dser_method:ident, $visit_method:ident, $type:ident, $read:ident) => (
101    fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
102      where V: Visitor<'de>,
103    {
104      let token = self.next_token()?;
105      if let Token::Value(SimpleValueRef::$type(value)) = token {
106        return visitor.$visit_method(self.parser.$read(value)?);
107      }
108      return Err(Error::Unexpected(stringify!($type), token));
109    }
110  );
111}
112macro_rules! complex {
113  ($token:ident, $self:ident, $visitor:ident . $method:ident) => (
114    {
115      let value = $visitor.$method(&mut *$self)?;
116      let token = $self.next_token()?;
117      if let Token::$token = token {
118        Ok(value)
119      } else {
120        Err(Error::Unexpected(stringify!($token), token))
121      }
122    }
123  );
124}
125impl<'de, 'a, R: Read + Seek> de::Deserializer<'de> for &'a mut Deserializer<R> {
126  type Error = Error;
127
128  #[inline]
129  fn is_human_readable(&self) -> bool { false }
130
131  primitive!(deserialize_i8 , visit_i8 , Char);
132  primitive!(deserialize_u8 , visit_u8 , Byte);
133  primitive!(deserialize_i16, visit_i16, Short);
134  primitive!(deserialize_u16, visit_u16, Word);
135  primitive!(deserialize_i32, visit_i32, Int);
136  primitive!(deserialize_u32, visit_u32, Dword);
137  primitive!(deserialize_i64, visit_i64, Int64, read_i64);
138  primitive!(deserialize_u64, visit_u64, Dword64, read_u64);
139  primitive!(deserialize_f32, visit_f32, Float);
140  primitive!(deserialize_f64, visit_f64, Double, read_f64);
141
142  fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
143    where V: Visitor<'de>,
144  {
145    let token = self.next_token()?;
146    if let Token::Value(SimpleValueRef::Byte(value)) = token {
147      return visitor.visit_bool(value != 0);
148    }
149    return Err(Error::Unexpected("Byte", token));
150  }
151  fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
152    where V: Visitor<'de>,
153  {
154    let token = self.next_token()?;
155    if let Token::Value(SimpleValueRef::Byte(value)) = token {
156      return visitor.visit_char(value as char);
157    }
158    if let Token::Value(SimpleValueRef::Char(value)) = token {
159      return visitor.visit_char(value as u8 as char);
160    }
161    return Err(Error::Unexpected("Byte, Char", token));
162  }
163
164  #[inline]
165  fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
166    where V: Visitor<'de>,
167  {
168    self.deserialize_string(visitor)
169  }
170  fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
171    where V: Visitor<'de>,
172  {
173    let token = self.next_token()?;
174    match token {
175      Token::Value(SimpleValueRef::String(value)) => {
176        visitor.visit_string(self.parser.read_string(value)?)
177      },
178      Token::Value(SimpleValueRef::ResRef(value)) => {
179        visitor.visit_string(self.parser.read_resref(value)?.as_string()?)
180      },
181      _ => Err(Error::Unexpected("String, ResRef", token)),
182    }
183  }
184  #[inline]
185  fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
186    where V: Visitor<'de>,
187  {
188    self.deserialize_byte_buf(visitor)
189  }
190  fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
191    where V: Visitor<'de>,
192  {
193    let token = self.next_token()?;
194    match token {
195      Token::Value(SimpleValueRef::Void(value)) => {
196        visitor.visit_byte_buf(self.parser.read_byte_buf(value)?)
197      },
198      Token::Value(SimpleValueRef::ResRef(value)) => {
199        visitor.visit_byte_buf(self.parser.read_resref(value)?.0)
200      },
201      _ => Err(Error::Unexpected("Void, ResRef", token)),
202    }
203  }
204
205  /// Всегда разбирает любое значение, как `Some(...)`, формат не умеет хранить признак
206  /// отсутствия значения. `None` в опциональные поля будет записываться только потому,
207  /// что при десериализации данное поле не будет найдено
208  #[inline]
209  fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
210    where V: Visitor<'de>,
211  {
212    visitor.visit_some(self)
213  }
214  /// Десериализует любую GFF структуру в `unit`, в остальных случаях выдает ошибку
215  #[inline]
216  fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
217    where V: Visitor<'de>,
218  {
219    let token = self.next_token()?;
220    match token {
221      Token::RootBegin { .. } |
222      Token::ItemBegin { .. } |
223      Token::StructBegin { .. } => {
224        self.parser.skip_next(token);
225        visitor.visit_unit()
226      },
227      token => Err(Error::Unexpected("RootBegin, ItemBegin, StructBegin", token)),
228    }
229  }
230
231  fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
232    where V: Visitor<'de>,
233  {
234    let token = self.next_token()?;
235    match token {
236      Token::Value(value)       => self.deserialize_value(value, visitor),
237      Token::ListBegin { .. }   => complex!(ListEnd, self, visitor.visit_seq),
238      Token::RootBegin { .. }   => complex!(RootEnd, self, visitor.visit_map),
239      Token::ItemBegin { .. }   => complex!(ItemEnd, self, visitor.visit_map),
240      Token::StructBegin { .. } => complex!(StructEnd, self, visitor.visit_map),
241      Token::Label(index) => {
242        let label = self.parser.read_label(index)?;
243        visitor.visit_str(label.as_str()?)
244      },
245      _ => unimplemented!("`deserialize_any`, token: {:?}", token)
246    }
247  }
248  fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
249    where V: Visitor<'de>,
250  {
251    let token = self.next_token()?;
252    self.parser.skip_next(token);
253    visitor.visit_none()
254  }
255  /// Данный метод вызывается при необходимости десериализовать идентификатор перечисления
256  fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
257    where V: Visitor<'de>,
258  {
259    use self::SimpleValueRef::*;
260
261    let token = self.next_token()?;
262    match token {
263      //TODO: После решения https://github.com/serde-rs/serde/issues/745 можно будет передавать числа
264      Token::Value(Byte(val))     => visitor.visit_string(val.to_string()),
265      Token::Value(Char(val))     => visitor.visit_string(val.to_string()),
266      Token::Value(Word(val))     => visitor.visit_string(val.to_string()),
267      Token::Value(Short(val))    => visitor.visit_string(val.to_string()),
268      Token::Value(Dword(val))    => visitor.visit_string(val.to_string()),
269      Token::Value(Int(val))      => visitor.visit_string(val.to_string()),
270      Token::Value(Dword64(val))  => visitor.visit_string(self.parser.read_u64(val)?.to_string()),
271      Token::Value(Int64(val))    => visitor.visit_string(self.parser.read_i64(val)?.to_string()),
272      Token::Value(String(val))   => visitor.visit_string(self.parser.read_string(val)?),
273      _ => Err(Error::Unexpected("Byte, Char, Word, Short, Dword, Int, Int64, String", token)),
274    }
275  }
276
277  fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
278    where V: Visitor<'de>,
279  {
280    let token = self.next_token()?;
281    match token {
282      Token::RootBegin   { .. } => complex!(RootEnd,   self, visitor.visit_map),
283      Token::ItemBegin   { .. } => complex!(ItemEnd,   self, visitor.visit_map),
284      Token::StructBegin { .. } => complex!(StructEnd, self, visitor.visit_map),
285      token => Err(Error::Unexpected("RootBegin, ItemBegin, StructBegin", token)),
286    }
287  }
288  fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
289    where V: Visitor<'de>,
290  {
291    let token = self.next_token()?;
292    match token {
293      Token::ListBegin { .. } => complex!(ListEnd, self, visitor.visit_seq),
294      token => Err(Error::Unexpected("ListBegin", token)),
295    }
296  }
297
298  /// Десериализует любую GFF структуру в `unit`, в остальных случаях выдает ошибку
299  #[inline]
300  fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
301    where V: Visitor<'de>,
302  {
303    self.deserialize_unit(visitor)
304  }
305  /// Разбирает в newtype структуру нижележащее значение
306  #[inline]
307  fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
308    where V: Visitor<'de>,
309  {
310    visitor.visit_newtype_struct(self)
311  }
312  fn deserialize_tuple<V>(self, len: usize, _visitor: V) -> Result<V::Value>
313    where V: Visitor<'de>,
314  {
315    let token = self.next_token()?;
316    unimplemented!("`deserialize_tuple(len: {})` not yet supported. Token: {:?}", len, token)
317  }
318  fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, _visitor: V) -> Result<V::Value>
319    where V: Visitor<'de>,
320  {
321    let token = self.next_token()?;
322    unimplemented!("`deserialize_tuple_struct(name: {}, len: {})` not yet supported. Token: {:?}", name, len, token)
323  }
324  fn deserialize_struct<V>(self, _name: &'static str, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
325    where V: Visitor<'de>,
326  {
327    self.deserialize_map(visitor)
328  }
329  fn deserialize_enum<V>(self, name: &'static str, variants: &'static [&'static str], _visitor: V) -> Result<V::Value>
330    where V: Visitor<'de>,
331  {
332    let token = self.next_token()?;
333    unimplemented!("`deserialize_enum(name: {}, variants: {})` not yet supported. Token: {:?}", name, variants.len(), token)
334  }
335}
336
337impl<'de, 'a, R: Read + Seek> de::MapAccess<'de> for &'a mut Deserializer<R> {
338  type Error = Error;
339
340  fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
341    where K: DeserializeSeed<'de>,
342  {
343    let token = self.peek_token()?.clone();
344    match token {
345      Token::RootEnd | Token::ItemEnd | Token::StructEnd => Ok(None),
346      Token::Label(..) => seed.deserialize(Field(&mut **self)).map(Some),
347      token => Err(Error::Unexpected("Label", token)),
348    }
349  }
350
351  #[inline]
352  fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
353    where V: DeserializeSeed<'de>,
354  {
355    seed.deserialize(&mut **self)
356  }
357}
358
359impl<'de, 'a, R: Read + Seek> de::SeqAccess<'de> for &'a mut Deserializer<R> {
360  type Error = Error;
361
362  fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
363    where T: DeserializeSeed<'de>,
364  {
365    let token = self.peek_token()?.clone();
366    match token {
367      Token::ListEnd => Ok(None),
368      Token::ItemBegin { .. } => seed.deserialize(&mut **self).map(Some),
369      token => Err(Error::Unexpected("ItemBegin", token)),
370    }
371  }
372}
373
374macro_rules! delegate {
375  ($dser_method:ident) => (
376    #[inline]
377    fn $dser_method<V>(self, visitor: V) -> Result<V::Value>
378      where V: Visitor<'de>,
379    {
380      (self.0).$dser_method(visitor)
381    }
382  );
383  ($dser_method:ident, name) => (
384    #[inline]
385    fn $dser_method<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
386      where V: Visitor<'de>,
387    {
388      (self.0).$dser_method(name, visitor)
389    }
390  );
391  ($dser_method:ident, names) => (
392    #[inline]
393    fn $dser_method<V>(self, name: &'static str, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
394      where V: Visitor<'de>,
395    {
396      (self.0).$dser_method(name, fields, visitor)
397    }
398  );
399}
400/// Десериализатор для чтения идентификаторов полей
401struct Field<'a, R: 'a + Read + Seek>(&'a mut Deserializer<R>);
402
403impl<'de, 'a, R: 'a + Read + Seek> de::Deserializer<'de> for Field<'a, R> {
404  type Error = Error;
405
406  #[inline]
407  fn is_human_readable(&self) -> bool { false }
408
409  fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
410    where V: Visitor<'de>,
411  {
412    let token = self.0.next_token()?;
413    if let Token::Label(index) = token {
414      let label = self.0.parser.read_label(index)?;
415      return visitor.visit_str(label.as_str()?);
416    }
417    return Err(Error::Unexpected("Label", token));
418  }
419
420  delegate!(deserialize_i8);
421  delegate!(deserialize_u8);
422  delegate!(deserialize_i16);
423  delegate!(deserialize_u16);
424  delegate!(deserialize_i32);
425  delegate!(deserialize_u32);
426  delegate!(deserialize_i64);
427  delegate!(deserialize_u64);
428  delegate!(deserialize_f32);
429  delegate!(deserialize_f64);
430
431  delegate!(deserialize_bool);
432  delegate!(deserialize_char);
433  delegate!(deserialize_str);
434  delegate!(deserialize_string);
435  delegate!(deserialize_bytes);
436  delegate!(deserialize_byte_buf);
437  delegate!(deserialize_option);
438  delegate!(deserialize_unit);
439  delegate!(deserialize_map);
440  delegate!(deserialize_seq);
441
442  delegate!(deserialize_any);
443  delegate!(deserialize_ignored_any);
444
445  delegate!(deserialize_unit_struct, name);
446  delegate!(deserialize_newtype_struct, name);
447  delegate!(deserialize_struct, names);
448  delegate!(deserialize_enum, names);
449
450  #[inline]
451  fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
452    where V: Visitor<'de>,
453  {
454    self.0.deserialize_tuple(len, visitor)
455  }
456  #[inline]
457  fn deserialize_tuple_struct<V>(self, name: &'static str, len: usize, visitor: V) -> Result<V::Value>
458    where V: Visitor<'de>,
459  {
460    self.0.deserialize_tuple_struct(name, len, visitor)
461  }
462}
463
464#[cfg(test)]
465mod empty_file {
466  //! Тестирование разбора пустого файла - содержащего только заголовок и структуру верхнего уровня
467  use std::fs::File;
468  use serde::Deserialize;
469  use super::Deserializer;
470
471  fn run<'de, T: Deserialize<'de>>(type_name: &str) -> T {
472    // Читаемый файл содержит только одну пустую структуру верхнего уровня
473    let file = File::open("test-data/empty.gff").expect("test file 'empty.gff' not exist");
474    let mut deserializer = Deserializer::new(file).expect("can't read GFF header");
475
476    Deserialize::deserialize(&mut deserializer).expect(&format!("can't deserialize to {}", type_name))
477  }
478
479  #[test]
480  fn to_unit() {
481    let _test: () = run("()");
482  }
483
484  #[test]
485  fn to_unit_struct() {
486    #[derive(Deserialize)]
487    struct Unit;
488
489    let _test: Unit = run("unit struct");
490  }
491
492  #[test]
493  fn to_empty_struct() {
494    #[derive(Deserialize)]
495    struct Empty {}
496
497    let _test: Empty = run("empty struct");
498  }
499
500  #[test]
501  #[should_panic(expected = "missing field `_value`")]
502  fn to_struct() {
503    #[derive(Deserialize)]
504    struct Struct { _value: i32 }
505
506    let _test: Struct = run("struct with fields");
507  }
508}