neotron_loader/traits.rs
1//! Traits to help us load information from different kinds of data source.
2
3// ============================================================================
4// Imports
5// ============================================================================
6
7// ============================================================================
8// Constants
9// ============================================================================
10
11// ============================================================================
12// Static Variables
13// ============================================================================
14
15// ============================================================================
16// Types
17// ============================================================================
18
19/// The error raised if you are reading from a [`Source`] which is a slice of
20/// bytes.
21#[derive(Debug, Clone)]
22pub struct SliceError;
23
24/// Describes something we can read data from
25pub trait Source {
26 type Error: core::fmt::Debug;
27
28 /// Read some bytes from the source.
29 ///
30 /// The bytes are read from the given offset, and there must be enough data
31 /// to fill `buffer` completely, otherwise an error is returned.
32 fn read(&self, offset: u32, buffer: &mut [u8]) -> Result<(), Self::Error>;
33
34 /// Read a 32-bit big-endian value.
35 fn read_u32_be(&self, offset: u32) -> Result<u32, Self::Error> {
36 let mut bytes = [0; 4];
37 self.read(offset, &mut bytes)?;
38 Ok(u32::from_be_bytes(bytes))
39 }
40
41 /// Read a 32-bit little-endian value.
42 fn read_u32_le(&self, offset: u32) -> Result<u32, Self::Error> {
43 let mut bytes = [0; 4];
44 self.read(offset, &mut bytes)?;
45 Ok(u32::from_le_bytes(bytes))
46 }
47
48 /// Read a 16-bit big-endian value.
49 fn read_u16_be(&self, offset: u32) -> Result<u16, Self::Error> {
50 let mut bytes = [0; 2];
51 self.read(offset, &mut bytes)?;
52 Ok(u16::from_be_bytes(bytes))
53 }
54
55 /// Read a 16-bit little-endian value.
56 fn read_u16_le(&self, offset: u32) -> Result<u16, Self::Error> {
57 let mut bytes = [0; 2];
58 self.read(offset, &mut bytes)?;
59 Ok(u16::from_le_bytes(bytes))
60 }
61
62 /// Read an 8-bit value.
63 fn read_u8(&self, offset: u32) -> Result<u8, Self::Error> {
64 let mut bytes = [0; 1];
65 self.read(offset, &mut bytes)?;
66 Ok(bytes[0])
67 }
68}
69
70impl Source for &[u8] {
71 type Error = SliceError;
72
73 fn read(&self, offset: u32, buffer: &mut [u8]) -> Result<(), Self::Error> {
74 let desired_len = buffer.len();
75 assert!(offset < (usize::MAX - desired_len) as u32);
76 let offset = offset as usize;
77 if let Some(sub_slice) = self.get(offset..offset + desired_len) {
78 buffer.copy_from_slice(sub_slice);
79 Ok(())
80 } else {
81 Err(SliceError)
82 }
83 }
84}
85
86// ============================================================================
87// Functions
88// ============================================================================
89
90// ============================================================================
91// Tests
92// ============================================================================
93
94// ============================================================================
95// End of File
96// ============================================================================