serde-tcod-config-parser 0.1.1

A best-effort implementation of the now deprecated libtcod config file parser functionality from libtcod
use crate::de::{Deserializer, Error};
use crate::lexer::Token;
use logos::Lexer;
use serde::de::{self, IntoDeserializer};

pub struct StructInternalAccess<'a, 'de> {
    de: &'a mut Deserializer<'de>,
    instance_name: Option<&'de str>,
    lexer: Option<Lexer<Token, &'de str>>,
}

impl<'a, 'de> StructInternalAccess<'a, 'de> {
    pub fn new(de: &'a mut Deserializer<'de>, instance_name: &'de str) -> Self {
        Self {
            de,
            instance_name: Some(instance_name),
            lexer: None,
        }
    }
}

impl<'de: 'a, 'a> de::MapAccess<'de> for StructInternalAccess<'a, 'de> {
    type Error = Error;

    fn next_key_seed<K>(
        &mut self,
        seed: K,
    ) -> Result<Option<<K as de::DeserializeSeed<'de>>::Value>, Self::Error>
    where
        K: de::DeserializeSeed<'de>,
    {
        if self.instance_name.is_some() {
            return seed
                .deserialize("instance_name".into_deserializer())
                .map(Some);
        }

        if self.de.lexer.token == Token::BraceClose {
            self.de.lexer.advance();
            return Ok(None);
        }

        if self.de.lexer.token != Token::Identifier {
            return unexpected_token!(self.de.lexer, "<field>");
        }
        let field = self.de.lexer.slice();

        self.lexer = Some(self.de.lexer.clone());
        self.de.lexer.advance();

        if self.de.lexer.token == Token::Assign
            || self.de.lexer.token == Token::Text
            || self.de.lexer.token == Token::BraceOpen
            || self.de.lexer.token == Token::Identifier
            || self.de.lexer.token == Token::BraceClose
        {
            seed.deserialize(field.into_deserializer()).map(Some)
        } else {
            self.lexer = None;
            Ok(None)
        }
    }

    fn next_value_seed<V>(
        &mut self,
        seed: V,
    ) -> Result<<V as de::DeserializeSeed<'de>>::Value, Self::Error>
    where
        V: de::DeserializeSeed<'de>,
    {
        if let Some(instance_name) = self.instance_name.take() {
            return seed.deserialize(de::value::BorrowedStrDeserializer::new(instance_name));
        }

        match self.de.lexer.token {
            Token::Assign => {
                self.lexer = None;
                self.de.lexer.advance();

                match self.de.lexer.token {
                    Token::Text
                    | Token::Char
                    | Token::Integer
                    | Token::Hex
                    | Token::Float
                    | Token::BracketOpen => seed.deserialize(&mut *self.de),
                    _ => unexpected_token!(self.de.lexer, "<value>"),
                }
            }
            Token::Text | Token::BraceOpen | Token::Identifier | Token::BraceClose => {
                self.de.lexer = self.lexer.take().unwrap();
                seed.deserialize(&mut *self.de)
            }
            _ => unexpected_token!(self.de.lexer, "= or \"<name>\""),
        }
    }
}