plasma_prp/core/
load_mask.rs1use std::io::{Read, Write};
9
10use anyhow::Result;
11
12use crate::resource::prp::PlasmaRead;
13
14#[derive(Clone, Copy, PartialEq, Eq, Hash)]
17pub struct LoadMask {
18 pub quality_lo: u8,
20 pub quality_hi: u8,
22}
23
24impl LoadMask {
25 pub const ALWAYS: LoadMask = LoadMask {
26 quality_lo: 0xFF,
27 quality_hi: 0xFF,
28 };
29
30 pub const NEVER: LoadMask = LoadMask {
31 quality_lo: 0,
32 quality_hi: 0,
33 };
34
35 pub fn from_byte(byte: u8) -> Self {
37 Self {
38 quality_lo: ((byte & 0xF0) >> 4) | 0xF0,
39 quality_hi: (byte & 0x0F) | 0xF0,
40 }
41 }
42
43 pub fn new(quality_lo: u8, quality_hi: u8) -> Self {
44 Self {
45 quality_lo,
46 quality_hi,
47 }
48 }
49
50 pub fn from_packed(byte: u8) -> Self {
53 Self {
54 quality_lo: ((byte & 0xF0) >> 4) | 0xF0,
55 quality_hi: (byte & 0x0F) | 0xF0,
56 }
57 }
58
59 pub fn is_used(&self) -> bool {
61 self.quality_lo != 0xFF || self.quality_hi != 0xFF
62 }
63
64 pub fn never_loads(&self) -> bool {
66 self.quality_lo == 0 && self.quality_hi == 0
67 }
68
69 pub fn read(reader: &mut impl Read) -> Result<Self> {
73 let byte = reader.read_u8()?;
74 let quality_lo = ((byte & 0xF0) >> 4) | 0xF0;
75 let quality_hi = (byte & 0x0F) | 0xF0;
76 Ok(Self {
77 quality_lo,
78 quality_hi,
79 })
80 }
81
82 pub fn write(&self, writer: &mut impl Write) -> Result<()> {
84 let byte = (self.quality_lo << 4) | (self.quality_hi & 0x0F);
85 writer.write_all(&[byte])?;
86 Ok(())
87 }
88}
89
90impl Default for LoadMask {
91 fn default() -> Self {
92 Self::ALWAYS
93 }
94}
95
96impl std::fmt::Debug for LoadMask {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 if *self == Self::ALWAYS {
99 write!(f, "LoadMask(Always)")
100 } else {
101 write!(
102 f,
103 "LoadMask(lo:{:#04x} hi:{:#04x})",
104 self.quality_lo, self.quality_hi
105 )
106 }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use std::io::Cursor;
114
115 #[test]
116 fn test_always() {
117 let m = LoadMask::ALWAYS;
118 assert!(!m.is_used());
119 assert!(!m.never_loads());
120 }
121
122 #[test]
123 fn test_never() {
124 let m = LoadMask::NEVER;
125 assert!(m.is_used());
126 assert!(m.never_loads());
127 }
128
129 #[test]
130 fn test_round_trip() {
131 let m = LoadMask::new(0xF3, 0xF5);
132 let mut buf = Vec::new();
133 m.write(&mut buf).unwrap();
134 assert_eq!(buf.len(), 1);
135
136 let mut cursor = Cursor::new(&buf);
137 let m2 = LoadMask::read(&mut cursor).unwrap();
138 assert_eq!(m, m2);
139 }
140
141 #[test]
142 fn test_always_round_trip() {
143 let m = LoadMask::ALWAYS;
144 let mut buf = Vec::new();
145 m.write(&mut buf).unwrap();
146
147 let mut cursor = Cursor::new(&buf);
148 let m2 = LoadMask::read(&mut cursor).unwrap();
149 assert_eq!(m, m2);
150 }
151}