1#[non_exhaustive]
5#[derive(Debug, Clone)]
6pub enum Value {
7 U32(u32),
9 I32(i32),
11 U64(u64),
13 Bool(bool),
15 Bytes(Vec<u8>),
17 Float(f64),
19 Array(Vec<Value>),
21}
22
23impl PartialEq for Value {
24 fn eq(&self, other: &Self) -> bool {
25 match (self, other) {
26 (Self::U32(a), Self::U32(b)) => a == b,
27 (Self::I32(a), Self::I32(b)) => a == b,
28 (Self::U64(a), Self::U64(b)) => a == b,
29 (Self::Bool(a), Self::Bool(b)) => a == b,
30 (Self::Bytes(a), Self::Bytes(b)) => a == b,
31 (Self::Float(a), Self::Float(b)) => a.to_bits() == b.to_bits(),
32 (Self::Array(a), Self::Array(b)) => a == b,
33 _ => false,
34 }
35 }
36}
37
38impl Eq for Value {}
39
40impl Value {
41 #[must_use]
43 pub fn truthy(&self) -> bool {
44 match self {
45 Self::Array(values) => !values.is_empty(),
46 Self::Float(value) => value.to_bits() != 0,
47 _ => self.try_as_u32().unwrap_or(1) != 0,
48 }
49 }
50
51 #[must_use]
53 pub fn to_bytes(&self) -> Vec<u8> {
54 match self {
55 Self::U32(value) => value.to_le_bytes().to_vec(),
56 Self::I32(value) => value.to_le_bytes().to_vec(),
57 Self::U64(value) => value.to_le_bytes().to_vec(),
58 Self::Bool(value) => u32::from(*value).to_le_bytes().to_vec(),
59 Self::Bytes(bytes) => bytes.clone(),
60 Self::Float(value) => value.to_le_bytes().to_vec(),
61 Self::Array(values) => values.iter().flat_map(Self::to_bytes).collect(),
62 }
63 }
64
65 #[must_use]
67 pub fn to_bytes_width(&self, declared_width: usize) -> Vec<u8> {
68 let mut bytes = self.to_bytes();
69 if declared_width == 0 {
70 return bytes;
71 }
72 bytes.resize(declared_width, 0);
73 bytes.truncate(declared_width);
74 bytes
75 }
76
77 #[must_use]
79 pub fn try_as_u32(&self) -> Option<u32> {
80 match self {
81 Self::U32(value) => Some(*value),
82 Self::I32(value) => u32::try_from(*value).ok(),
83 Self::U64(value) => u32::try_from(*value).ok(),
84 Self::Bool(value) => Some(u32::from(*value)),
85 Self::Bytes(bytes) => (bytes.len() <= 4).then(|| read_u32_prefix(bytes)),
86 Self::Float(value) => Some(*value as u32),
87 Self::Array(_) => None,
88 }
89 }
90
91 #[must_use]
93 pub fn as_u32(&self) -> u32 {
94 self.try_as_u32().unwrap_or(0)
95 }
96
97 #[must_use]
99 pub fn try_as_u64(&self) -> Option<u64> {
100 match self {
101 Self::U32(value) => Some(u64::from(*value)),
102 Self::I32(value) => u64::try_from(*value).ok(),
103 Self::U64(value) => Some(*value),
104 Self::Bool(value) => Some(u64::from(*value)),
105 Self::Bytes(bytes) => (bytes.len() <= 8).then(|| read_u64_prefix(bytes)),
106 Self::Float(value) => Some(*value as u64),
107 Self::Array(_) => None,
108 }
109 }
110
111 #[must_use]
113 pub fn as_u64(&self) -> u64 {
114 self.try_as_u64().unwrap_or(0)
115 }
116
117 #[must_use]
119 pub fn wide_bytes(&self) -> Vec<u8> {
120 self.to_bytes()
121 }
122
123 #[must_use]
125 pub fn zero_for(ty: vyre::ir::DataType) -> Self {
126 Self::try_zero_for(ty).unwrap_or_else(|| Self::Bytes(Vec::new()))
127 }
128
129 #[must_use]
131 pub fn try_zero_for(ty: vyre::ir::DataType) -> Option<Self> {
132 match ty {
133 vyre::ir::DataType::U32 => Some(Self::U32(0)),
134 vyre::ir::DataType::I32 => Some(Self::I32(0)),
135 vyre::ir::DataType::U64 => Some(Self::U64(0)),
136 vyre::ir::DataType::Bool => Some(Self::Bool(false)),
137 vyre::ir::DataType::Bytes => Some(Self::Bytes(Vec::new())),
138 vyre::ir::DataType::Vec2U32 => Some(Self::Bytes(vec![0; 8])),
139 vyre::ir::DataType::Vec4U32 => Some(Self::Bytes(vec![0; 16])),
140 _ => None,
141 }
142 }
143
144 pub fn from_element_bytes(ty: vyre::ir::DataType, bytes: &[u8]) -> Result<Self, String> {
150 match ty {
151 vyre::ir::DataType::U32 => {
152 if bytes.len() < 4 {
153 return Err("u32 requires 4 bytes".to_string());
154 }
155 Ok(Self::U32(u32::from_le_bytes([
156 bytes[0], bytes[1], bytes[2], bytes[3],
157 ])))
158 }
159 vyre::ir::DataType::I32 => {
160 if bytes.len() < 4 {
161 return Err("i32 requires 4 bytes".to_string());
162 }
163 Ok(Self::I32(i32::from_le_bytes([
164 bytes[0], bytes[1], bytes[2], bytes[3],
165 ])))
166 }
167 vyre::ir::DataType::U64 => {
168 if bytes.len() < 8 {
169 return Err("u64 requires 8 bytes".to_string());
170 }
171 Ok(Self::U64(u64::from_le_bytes([
172 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
173 ])))
174 }
175 vyre::ir::DataType::Bool => {
176 if bytes.len() < 4 {
177 return Err("bool requires 4 bytes".to_string());
178 }
179 Ok(Self::Bool(
180 u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) != 0,
181 ))
182 }
183 vyre::ir::DataType::Vec2U32 => {
184 if bytes.len() < 8 {
185 return Err("vec2u32 requires 8 bytes".to_string());
186 }
187 Ok(Self::Bytes(bytes[..8].to_vec()))
188 }
189 vyre::ir::DataType::Vec4U32 => {
190 if bytes.len() < 16 {
191 return Err("vec4u32 requires 16 bytes".to_string());
192 }
193 Ok(Self::Bytes(bytes[..16].to_vec()))
194 }
195 vyre::ir::DataType::F32 => {
196 if bytes.len() < 4 {
197 return Err("f32 requires 4 bytes".to_string());
198 }
199 Ok(Self::Float(f64::from(f32::from_le_bytes([
200 bytes[0], bytes[1], bytes[2], bytes[3],
201 ]))))
202 }
203 vyre::ir::DataType::Bytes => Ok(Self::Bytes(bytes.to_vec())),
204 _ => Ok(Self::Bytes(bytes.to_vec())),
205 }
206 }
207}
208
209fn read_u32_prefix(bytes: &[u8]) -> u32 {
210 let mut padded = [0u8; 4];
211 let len = bytes.len().min(4);
212 padded[..len].copy_from_slice(&bytes[..len]);
213 u32::from_le_bytes(padded)
214}
215
216fn read_u64_prefix(bytes: &[u8]) -> u64 {
217 let mut padded = [0u8; 8];
218 let len = bytes.len().min(8);
219 padded[..len].copy_from_slice(&bytes[..len]);
220 u64::from_le_bytes(padded)
221}