solana_bytes_reader/
utils.rs

1use solana_program_error::ProgramError;
2
3
4/// # Safety
5/// The caller is responsible for ensuring that the range `[start..start + 8]`
6/// is within bounds of the `data` slice.
7pub fn read_u64_slice(data: &[u8], start: usize) -> Result<u64, ProgramError> {
8    Ok(
9        u64::from_le_bytes(data[start..start + 8]
10            .try_into()
11            .map_err(|_| ProgramError::InvalidInstructionData)?
12        )
13    )
14}
15
16/// # Safety
17/// The caller is responsible for ensuring that the range `[start..start + 8]`
18/// is within bounds of the `data` slice.
19pub fn read_i64_slice(data: &[u8], start: usize) -> Result<i64, ProgramError> {
20    Ok(
21        i64::from_le_bytes(data[start..start + 8]
22            .try_into()
23            .map_err(|_| ProgramError::InvalidInstructionData)?
24        )
25    )
26}
27
28/// # Safety
29/// The caller is responsible for ensuring that the range `[start..start + 4]`
30/// is within bounds of the `data` slice.
31pub fn read_u32_slice(data: &[u8], start: usize) -> Result<u32, ProgramError> {
32    Ok(
33        u32::from_le_bytes(data[start..start + 4]
34            .try_into()
35            .map_err(|_| ProgramError::InvalidInstructionData)?
36        )
37    )
38}
39
40/// # Safety
41/// The caller is responsible for ensuring that the range `[start..start + 4]`
42/// is within bounds of the `data` slice.
43pub fn read_i32_slice(data: &[u8], start: usize) -> Result<i32, ProgramError> {
44    Ok(
45        i32::from_le_bytes(data[start..start + 4]
46            .try_into()
47            .map_err(|_| ProgramError::InvalidInstructionData)?
48        )
49    )
50}
51
52/// # Safety
53/// The caller is responsible for ensuring that the range `[start..start + 2]`
54/// is within bounds of the `data` slice.
55pub fn read_u16_slice(data: &[u8], start: usize) -> Result<u16, ProgramError> {
56    Ok(
57        u16::from_le_bytes(data[start..start + 2]
58            .try_into()
59            .map_err(|_| ProgramError::InvalidInstructionData)?
60        )
61    )
62}
63
64/// # Safety
65/// The caller is responsible for ensuring that the range `[start..start + 2]`
66/// is within bounds of the `data` slice.
67pub fn read_i16_slice(data: &[u8], start: usize) -> Result<i16, ProgramError> {
68    Ok(
69        i16::from_le_bytes(data[start..start + 2]
70            .try_into()
71            .map_err(|_| ProgramError::InvalidInstructionData)?
72        )
73    )
74}
75
76/// # Safety
77/// This function returns an error instead of panicking if the index is out of bounds.
78/// Valid values are 0 (false) and 1 (true). Any other value results in an error.
79pub fn read_bool_slice(data: &[u8], start: usize) -> Result<bool, ProgramError> {
80    Ok(
81        match data.get(start).copied() {
82            Some(0) => false,
83            Some(1) => true,
84            _ => return Err(ProgramError::InvalidInstructionData)
85        }
86    )
87}
88
89/// If this is a standalone function, consider simply using `bytes[i]`,
90/// because in that case it's just a unneccessary indirection.
91///
92/// # Safety
93/// This function returns an error instead of panicking if the index is out of bounds.
94pub fn read_u8_slice(data: &[u8], start: usize) -> Result<u8, ProgramError> {
95    data.get(start).map(|&i| i).ok_or(ProgramError::InvalidInstructionData)
96}
97
98/// # Safety
99/// This function returns an error instead of panicking if the index is out of bounds.
100pub fn read_i8_slice(data: &[u8], start: usize) -> Result<i8, ProgramError> {
101    data.get(start).map(|&i| i as i8).ok_or(ProgramError::InvalidInstructionData)
102}
103
104/// Reads `const N` amount of bytes.
105/// 
106/// # Safety
107/// The caller is responsible for ensuring that the range `[start..start + N]`
108/// is within bounds of the `data` slice.
109pub fn read_bytes_slice<const N: usize>(data: &[u8], start: usize) -> Result<[u8; N], ProgramError> {
110    Ok(
111        data[start..start + N]
112            .try_into()
113            .map_err(|_| ProgramError::InvalidInstructionData)?
114    )
115}