vdf-reader 0.3.3

Rust parser for valve vdf files.
Documentation
use super::{Entry, Table};
use crate::entry::Value;
use crate::error::{ParseStringError, UnknownError};
use crate::VdfError;
use serde_core::de::{DeserializeSeed, SeqAccess};
use serde_core::{Deserialize, Deserializer, Serialize, Serializer};
use std::ops::{Deref, DerefMut};

/// An array of entries (items that have the same key).
#[derive(Clone, PartialEq, Eq, Debug, Default)]
pub struct Array(Vec<Entry>);

impl Array {
    pub(crate) fn from_space_separated(str: &str) -> Self {
        let items = str
            .split(' ')
            .filter(|part| !part.is_empty())
            .map(Value::from)
            .map(Entry::from)
            .collect();
        Array(items)
    }
}

impl<'de> Deserialize<'de> for Array {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        <Vec<Entry>>::deserialize(deserializer).map(Array)
    }
}

impl Serialize for Array {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        self.0.serialize(serializer)
    }
}

impl From<Vec<Entry>> for Array {
    fn from(value: Vec<Entry>) -> Self {
        Array(value)
    }
}
impl From<Entry> for Array {
    fn from(value: Entry) -> Self {
        Array(vec![value])
    }
}

impl From<Array> for Entry {
    fn from(array: Array) -> Self {
        Entry::Array(array)
    }
}

impl Deref for Array {
    type Target = Vec<Entry>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl DerefMut for Array {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

pub(crate) struct ArraySeq {
    iter: std::vec::IntoIter<Entry>,
}

impl ArraySeq {
    pub(crate) fn new(array: Array) -> Self {
        ArraySeq {
            iter: array.0.into_iter(),
        }
    }
}

impl<'de> SeqAccess<'de> for ArraySeq {
    type Error = VdfError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
    where
        T: DeserializeSeed<'de>,
    {
        let next = match self.iter.next() {
            Some(next) => next,
            None => return Ok(None),
        };

        seed.deserialize(next).map(Some)
    }
}

pub(crate) struct TableArraySeq {
    iter: std::vec::IntoIter<(String, Entry)>,
    last_key: Option<u64>,
}

impl TableArraySeq {
    pub(crate) fn new(table: Table) -> Self {
        // since the tables map doesn't have a stable order, we need to re-sort them to have the keys in order
        let mut items: Vec<_> = table.into_iter().collect();
        items.sort_by(|(key_a, _), (key_b, _)| key_a.cmp(key_b));
        TableArraySeq {
            iter: items.into_iter(),
            last_key: None,
        }
    }
}

impl<'de> SeqAccess<'de> for TableArraySeq {
    type Error = VdfError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
    where
        T: DeserializeSeed<'de>,
    {
        let (key, next) = match self.iter.next() {
            Some(next) => next,
            None => return Ok(None),
        };

        let key: u64 = key.parse().map_err(|_| {
            VdfError::ParseString(ParseStringError {
                ty: "u64",
                value: key,
            })
        })?;

        if let Some(last_key) = self.last_key {
            let expected_key = last_key + 1;
            if expected_key != key {
                return Err(VdfError::Other(UnknownError::from(format!(
                    "Invalid array key {key}, expected {expected_key}"
                ))));
            }
        }
        self.last_key = Some(key);

        seed.deserialize(next).map(Some)
    }
}