serde-gff 0.3.0

https://github.com/Mingun/serde-gff
Documentation
//! Содержит описания значений, которые может хранить GFF файл

use indexmap::IndexMap;

use crate::{Label, LocString, ResRef};
use crate::index::{U64Index, I64Index, F64Index, StringIndex, ResRefIndex, LocStringIndex, BinaryIndex};

/// Перечисление, представляющее все примитивные типы данных, который может хранить GFF файл.
///
/// Кроме примитивных типов данных GFF файл также может хранить рекурсивные структуры из
/// данных типов и их списки.
#[derive(Debug, Clone, PartialEq)]
pub enum SimpleValueRef {
  /// Беззнаковое байтовое значение (от 0 до 255), занимающее один байт.
  ///
  /// Тег, ассоциированный с типом, равен `0`.
  Byte(u8),
  /// Символ текста в диапазоне `0x00-0xFF`, занимающий один байт.
  ///
  /// Тег, ассоциированный с типом, равен `1`.
  Char(i8),
  /// Беззнаковое целое (от 0 до 65535), занимающее 2 байта.
  ///
  /// Тег, ассоциированный с типом, равен `2`.
  Word(u16),
  /// Знаковое целое (от -32768 до 32767), занимающее 2 байта.
  ///
  /// Тег, ассоциированный с типом, равен `3`.
  Short(i16),
  /// Беззнаковое целое (от 0 до 4294967296), занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `4`.
  Dword(u32),
  /// Знаковое целое (от -2147483648 до 2147483647), занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `5`.
  Int(i32),
  /// Беззнаковое целое (от 0 до примерно 18e+18), занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `6`.
  Dword64(U64Index),
  /// Знаковое целое (примерно от -9e+18 до +9e+18), занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `7`.
  Int64(I64Index),
  /// Число с плавающей запятой одинарной точности, занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `8`.
  Float(f32),
  /// Число с плавающей запятой двойной точности, занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `9`.
  Double(F64Index),
  /// Нелокализуемая строка.
  ///
  /// Предпочитаемый максимальный размер - 1024 символа. Это ограничение установлено в первую
  /// очередь для того, чтобы сохранить пропускную способность сети в том случае, если строку
  /// необходимо передавать с сервера на клиент.
  ///
  /// Данный вид строк не должен использоваться для текста, который может увидеть игрок, так как
  /// он будет одинаковым независимо от языка клиента игры. Область применения данного типа -
  /// текст для разработчиков/дизайнеров уровней, например, тегов объектов, используемых в скриптах.
  ///
  /// Тег, ассоциированный с типом, равен `10`.
  String(StringIndex),
  /// Имя файла ресурса, до 16 символов.
  ///
  /// Тег, ассоциированный с типом, равен `11`.
  ResRef(ResRefIndex),
  /// Локализуемая строка. Содержит `StringRef` и несколько `CExoString`, каждую со своим номером языка.
  ///
  /// Тег, ассоциированный с типом, равен `12`.
  LocString(LocStringIndex),
  /// Произвольные данные любой длины.
  ///
  /// Тег, ассоциированный с типом, равен `13`.
  Void(BinaryIndex),
}

/// Перечисление, представляющее все примитивные типы данных, который может хранить GFF файл.
/// В отличие от [`SimpleValueRef`] содержит полностью прочитанные данные из файла, а не только
/// ссылки на них
///
/// Кроме примитивных типов данных GFF файл также может хранить рекурсивные структуры из
/// данных типов и их списки.
///
/// [`SimpleValueRef`]: enum.SimpleValueRef.html
#[derive(Debug, Clone, PartialEq)]
pub enum SimpleValue {
  /// Беззнаковое байтовое значение (от 0 до 255), занимающее один байт.
  ///
  /// Тег, ассоциированный с типом, равен `0`.
  Byte(u8),
  /// Символ текста в диапазоне `0x00-0xFF`, занимающий один байт.
  ///
  /// Тег, ассоциированный с типом, равен `1`.
  Char(i8),
  /// Беззнаковое целое (от 0 до 65535), занимающее 2 байта.
  ///
  /// Тег, ассоциированный с типом, равен `2`.
  Word(u16),
  /// Знаковое целое (от -32768 до 32767), занимающее 2 байта.
  ///
  /// Тег, ассоциированный с типом, равен `3`.
  Short(i16),
  /// Беззнаковое целое (от 0 до 4294967296), занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `4`.
  Dword(u32),
  /// Знаковое целое (от -2147483648 до 2147483647), занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `5`.
  Int(i32),
  /// Беззнаковое целое (от 0 до примерно 18e+18), занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `6`.
  Dword64(u64),
  /// Знаковое целое (примерно от -9e+18 до +9e+18), занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `7`.
  Int64(i64),
  /// Число с плавающей запятой одинарной точности, занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `8`.
  Float(f32),
  /// Число с плавающей запятой двойной точности, занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `9`.
  Double(f64),
  /// Нелокализуемая строка.
  ///
  /// Предпочитаемый максимальный размер - 1024 символа. Это ограничение установлено в первую
  /// очередь для того, чтобы сохранить пропускную способность сети в том случае, если строку
  /// необходимо передавать с сервера на клиент.
  ///
  /// Данный вид строк не должен использоваться для текста, который может увидеть игрок, так как
  /// он будет одинаковым независимо от языка клиента игры. Область применения данного типа -
  /// текст для разработчиков/дизайнеров уровней, например, тегов объектов, используемых в скриптах.
  ///
  /// Тег, ассоциированный с типом, равен `10`.
  String(String),
  /// Имя файла ресурса, до 16 символов.
  ///
  /// Тег, ассоциированный с типом, равен `11`.
  ResRef(ResRef),
  /// Локализуемая строка. Содержит `StringRef` и несколько `CExoString`, каждую со своим номером языка.
  ///
  /// Тег, ассоциированный с типом, равен `12`.
  LocString(LocString),
  /// Произвольные данные любой длины.
  ///
  /// Тег, ассоциированный с типом, равен `13`.
  Void(Vec<u8>),
}

/// Перечисление, представляющее все возможные типы данных, которых способен хранить GFF файл,
/// в обобщенном виде. Аналог `serde_json::Value`
#[derive(Debug, Clone, PartialEq)]
pub enum Value {
  /// Беззнаковое байтовое значение (от 0 до 255), занимающее один байт.
  ///
  /// Тег, ассоциированный с типом, равен `0`.
  Byte(u8),
  /// Символ текста в диапазоне `0x00-0xFF`, занимающий один байт.
  ///
  /// Тег, ассоциированный с типом, равен `1`.
  Char(i8),
  /// Беззнаковое целое (от 0 до 65535), занимающее 2 байта.
  ///
  /// Тег, ассоциированный с типом, равен `2`.
  Word(u16),
  /// Знаковое целое (от -32768 до 32767), занимающее 2 байта.
  ///
  /// Тег, ассоциированный с типом, равен `3`.
  Short(i16),
  /// Беззнаковое целое (от 0 до 4294967296), занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `4`.
  Dword(u32),
  /// Знаковое целое (от -2147483648 до 2147483647), занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `5`.
  Int(i32),
  /// Беззнаковое целое (от 0 до примерно 18e+18), занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `6`.
  Dword64(u64),
  /// Знаковое целое (примерно от -9e+18 до +9e+18), занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `7`.
  Int64(i64),
  /// Число с плавающей запятой одинарной точности, занимающее 4 байта.
  ///
  /// Тег, ассоциированный с типом, равен `8`.
  Float(f32),
  /// Число с плавающей запятой двойной точности, занимающее 8 байт.
  ///
  /// Тег, ассоциированный с типом, равен `9`.
  Double(f64),
  /// Нелокализуемая строка.
  ///
  /// Предпочитаемый максимальный размер - 1024 символа. Это ограничение установлено в первую
  /// очередь для того, чтобы сохранить пропускную способность сети в том случае, если строку
  /// необходимо передавать с сервера на клиент.
  ///
  /// Данный вид строк не должен использоваться для текста, который может увидеть игрок, так как
  /// он будет одинаковым независимо от языка клиента игры. Область применения данного типа -
  /// текст для разработчиков/дизайнеров уровней, например, тегов объектов, используемых в скриптах.
  ///
  /// Тег, ассоциированный с типом, равен `10`.
  String(String),
  /// Имя файла ресурса, до 16 символов.
  ///
  /// Тег, ассоциированный с типом, равен `11`.
  ResRef(ResRef),
  /// Локализуемая строка. Содержит `StringRef` и несколько `CExoString`, каждую со своим номером языка.
  ///
  /// Тег, ассоциированный с типом, равен `12`.
  LocString(LocString),
  /// Произвольные данные любой длины.
  ///
  /// Тег, ассоциированный с типом, равен `13`.
  Void(Vec<u8>),
  /// Вложенная структура. Порядок полей в структуре постоянный и определяется порядком их добавления
  ///
  /// Тег, ассоциированный с типом, равен `14`.
  Struct(IndexMap<Label, Value>),
  /// Список значений любой длины.
  ///
  /// Тег, ассоциированный с типом, равен `15`.
  List(Vec<Value>),
}

impl From<SimpleValue> for Value {
  #[inline]
  fn from(value: SimpleValue) -> Value {
    use self::SimpleValue::*;

    match value {
      Byte(val)      => Value::Byte(val),
      Char(val)      => Value::Char(val),
      Word(val)      => Value::Word(val),
      Short(val)     => Value::Short(val),
      Dword(val)     => Value::Dword(val),
      Int(val)       => Value::Int(val),
      Dword64(val)   => Value::Dword64(val),
      Int64(val)     => Value::Int64(val),
      Float(val)     => Value::Float(val),
      Double(val)    => Value::Double(val),
      String(val)    => Value::String(val),
      ResRef(val)    => Value::ResRef(val),
      LocString(val) => Value::LocString(val),
      Void(val)      => Value::Void(val),
    }
  }
}