rscache 0.2.2

A simple RuneScape cache utility.
Documentation
use crate::{ CacheError, codec::Compression, codec };

#[derive(Debug, Clone)]
pub struct Entry {
    pub crc: u32,
    pub revision: u32,
}

/// Used to check the validity of the cache.
#[derive(Clone, Debug, Default)]
pub struct Checksum {
    entries: Vec<Entry>
}

impl Checksum {
    #[doc(hidden)]
    #[inline]
    pub const fn new() -> Self {
        Self { entries: Vec::new() }
    }

    #[doc(hidden)]
    #[inline]
    pub fn push(&mut self, entry: Entry) {
        self.entries.push(entry);
    }

    /// Validates the given crcs with internal crcs of the `Checksum`.
    /// 
    /// # Examples
    /// 
    /// ```
    /// # use rscache::{ Cache, CacheError };
    /// # fn main() -> Result<(), CacheError> {
    /// # let path = "./data/cache";
    /// # let cache = Cache::new(path)?;
    /// # let checksum = cache.create_checksum()?;
    /// // client crcs:
    /// let crcs = vec![1593884597, 1029608590, 16840364, 4209099954, 3716821437, 165713182, 
    ///                 686540367, 4262755489, 2208636505, 3047082366, 586413816, 2890424900, 
    ///                 3411535427, 3178880569, 153718440, 3849392898, 0, 2813112885, 1461700456, 
    ///                 2751169400, 2927815226];
    /// 
    /// let valid = checksum.validate_crcs(&crcs);
    /// 
    /// assert_eq!(valid, true);
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn validate_crcs(&self, crcs: &[u32]) -> bool {
        let owned_crcs: Vec<u32> = self.entries.iter()
            .map(|entry| entry.crc)
            .collect();
        
        owned_crcs == crcs
    }

    /// Consumes the `Checksum` and encodes it into a byte buffer.
    /// 
    /// After encoding the checksum it can be sent to the client.
    /// 
    /// # Errors
    /// 
    /// Returns a `CacheError` if the encoding fails.
    /// 
    /// # Examples
    /// 
    /// ```
    /// # use rscache::{ Cache, CacheError, Checksum };
    /// # use std::net::TcpStream;
    /// # use std::io::Write;
    /// fn encode_checksum(checksum: Checksum, stream: &mut TcpStream) -> Result<(), CacheError> {
    ///     let buffer = checksum.encode()?;
    /// 
    ///     stream.write_all(&buffer)?;
    ///     Ok(())
    /// }
    /// ```
    #[inline]
    pub fn encode(self) -> Result<Vec<u8>, CacheError> {
        let mut buffer = Vec::with_capacity(self.entries.len() * 2 * 4);

		for entry in self.entries {
            buffer.extend_from_slice(&u32::to_be_bytes(entry.crc));
            buffer.extend_from_slice(&u32::to_be_bytes(entry.revision));
        }

        Ok(codec::encode(Compression::None, &buffer, None)?)
    }
}