serde_gff/de/
string.rs

1//! Содержит реализацию конвертирования типа GFF строки в десериализатор
2//! с помощью которого из него могут быть прочитаны другие совместимые типы.
3
4use std::marker::PhantomData;
5
6use serde::forward_to_deserialize_any;
7use serde::de::{Deserializer, Error, IntoDeserializer, Visitor};
8
9use crate::string::{GffString, StringKey};
10
11impl<'de, E> IntoDeserializer<'de, E> for StringKey
12  where E: Error,
13{
14  type Deserializer = StringKeyDeserializer<E>;
15
16  #[inline]
17  fn into_deserializer(self) -> Self::Deserializer {
18    StringKeyDeserializer { value: self, marker: PhantomData }
19  }
20}
21
22/// Десериализатор, использующий в качестве источника данных тип [`StringKey`].
23///
24/// Позволяет прочитать из ключа число, сформированное по формуле:
25/// ```rust,ignore
26/// ((language as u32) << 1) | gender as u32
27/// ```
28/// Именно в таком формате оно храниться в GFF файле.
29///
30/// [`StringKey`]: ../../enum.StringKey.html
31#[derive(Debug)]
32pub struct StringKeyDeserializer<E> {
33  /// Источник данных, из которого достаются данные для десериализации других структур
34  value: StringKey,
35  /// Фиктивный элемент, для связывания типа ошибки `E`
36  marker: PhantomData<E>,
37}
38
39impl<'de, E> Deserializer<'de> for StringKeyDeserializer<E>
40  where E: Error,
41{
42  type Error = E;
43
44  fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
45    where V: Visitor<'de>,
46  {
47    visitor.visit_u32(self.value.into())
48  }
49
50  forward_to_deserialize_any!(
51    bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
52    string bytes byte_buf option unit unit_struct newtype_struct seq
53    tuple tuple_struct map struct enum identifier ignored_any
54  );
55}
56
57///////////////////////////////////////////////////////////////////////////////////////////////////
58
59impl<'de, E> IntoDeserializer<'de, E> for GffString
60  where E: Error,
61{
62  type Deserializer = GffStringDeserializer<E>;
63
64  #[inline]
65  fn into_deserializer(self) -> Self::Deserializer {
66    GffStringDeserializer { value: self, marker: PhantomData }
67  }
68}
69
70/// Десериализатор, использующий в качестве источника данных тип [`GffString`].
71///
72/// В зависимости от типа хранимой строки позволяет прочитать из значения либо `u32`,
73/// являющемся StrRef индексом, либо отображение из `u32` (содержащего комбинированное
74/// значение языка и пола строки) на `String` с текстом строки для данного языка и пола.
75///
76/// [`GffString`]: ../../enum.GffString.html
77#[derive(Debug)]
78pub struct GffStringDeserializer<E> {
79  /// Источник данных, из которого достаются данные для десериализации других структур
80  value: GffString,
81  /// Фиктивный элемент, для связывания типа ошибки `E`
82  marker: PhantomData<E>,
83}
84impl<'de, E> Deserializer<'de> for GffStringDeserializer<E>
85  where E: Error,
86{
87  type Error = E;
88
89  fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
90    where V: Visitor<'de>,
91  {
92    use self::GffString::*;
93
94    match self.value {
95      External(str_ref) => visitor.visit_u32(str_ref.0),
96      Internal(strings) => visitor.visit_map(strings.into_deserializer()),
97    }
98  }
99
100  forward_to_deserialize_any!(
101    bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
102    string bytes byte_buf option unit unit_struct newtype_struct seq
103    tuple tuple_struct map struct enum identifier ignored_any
104  );
105}