1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::{
    containers::Bytes,
    derive,
    io::Source,
    tes3::{Error, Result},
};
use std::io::Write;

/// Represents a file within the TES3 virtual filesystem.
#[derive(Clone, Debug, Default)]
pub struct File<'bytes> {
    pub(crate) bytes: Bytes<'bytes>,
}

type ReadResult<T> = T;
derive::bytes!(File);
derive::reader!(File => ReadResult);

impl<'bytes> File<'bytes> {
    pub fn write<Out>(&self, stream: &mut Out) -> Result<()>
    where
        Out: ?Sized + Write,
    {
        stream.write_all(self.as_bytes())?;
        Ok(())
    }

    #[allow(clippy::unnecessary_wraps)]
    fn do_read<In>(stream: &mut In) -> Result<ReadResult<Self>>
    where
        In: ?Sized + Source<'bytes>,
    {
        Ok(Self {
            bytes: stream.read_bytes_to_end(),
        })
    }
}

impl<'bytes, const N: usize> From<&'bytes [u8; N]> for File<'bytes> {
    fn from(value: &'bytes [u8; N]) -> Self {
        Self::from(value.as_slice())
    }
}

impl<'bytes> From<&'bytes [u8]> for File<'bytes> {
    fn from(value: &'bytes [u8]) -> Self {
        Self {
            bytes: Bytes::from_borrowed(value),
        }
    }
}

impl From<Box<[u8]>> for File<'static> {
    fn from(value: Box<[u8]>) -> Self {
        Self {
            bytes: Bytes::from_owned(value),
        }
    }
}

#[cfg(test)]
mod tests {
    use crate::tes3::File;

    #[test]
    fn default_state() {
        let f = File::new();
        assert!(f.is_empty());
        assert!(f.len() == 0);
        assert!(f.as_bytes().is_empty());
    }
}