exolvl 0.12.0

A library for reading and writing Exoracer level files.
Documentation
use super::{author_replay::AuthorReplay, level_data::LevelData, local_level::LocalLevel};
use crate::{Read, ReadVersioned, Write, error::Error};
use uuid::Uuid;

/// A full Exoracer level.
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Exolvl {
    /// The local level data for this level.
    pub local_level: LocalLevel,
    /// The actual level data.
    pub level_data: LevelData,
    /// The data for the author time replay.
    pub author_replay: AuthorReplay,
}

const EXPECTED_MAGIC: &[u8; 4] = b"NYA^";

impl Read for Exolvl {
    #[cfg_attr(
        feature = "tracing",
        tracing::instrument(level = "debug", name = "Exolvl::read", skip(input))
    )]
    fn read(input: &mut impl std::io::Read) -> Result<Self, Error> {
        let magic: [u8; 4] = Read::read(input)?;

        #[cfg(feature = "tracing")]
        debug!(?magic);

        if &magic != EXPECTED_MAGIC {
            return Err(Error::WrongMagic);
        }

        let local_level = LocalLevel::read(input)?;
        let level_data = ReadVersioned::read(input, local_level.serialization_version)?;
        let author_replay = Read::read(input)?;

        Ok(Self {
            local_level,
            level_data,
            author_replay,
        })
    }
}

impl Write for Exolvl {
    fn write(&self, output: &mut impl std::io::Write) -> Result<(), Error> {
        EXPECTED_MAGIC.write(output)?;
        self.local_level.write(output)?;
        self.level_data.write(output)?;
        self.author_replay.write(output)
    }
}

impl Default for Exolvl {
    fn default() -> Self {
        let level_id = Uuid::new_v4();

        Self {
            local_level: LocalLevel::default_with_id(level_id),
            level_data: LevelData::default_with_id(level_id),
            author_replay: AuthorReplay::default(),
        }
    }
}