Skip to content

Commit b3721af

Browse files
committed
feat: Custom const for ERROR_TYPE (#756)
1 parent a8c2ca9 commit b3721af

File tree

1 file changed

+60
-6
lines changed

1 file changed

+60
-6
lines changed

src/extension/prelude.rs

+60-6
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,11 @@ pub fn new_array_op(element_ty: Type, size: u64) -> LeafOp {
137137
.into()
138138
}
139139

140+
/// The custom type for Errors.
141+
pub const ERROR_CUSTOM_TYPE: CustomType =
142+
CustomType::new_simple(ERROR_TYPE_NAME, PRELUDE_ID, TypeBound::Eq);
140143
/// Unspecified opaque error type.
141-
pub const ERROR_TYPE: Type = Type::new_extension(CustomType::new_simple(
142-
ERROR_TYPE_NAME,
143-
PRELUDE_ID,
144-
TypeBound::Eq,
145-
));
144+
pub const ERROR_TYPE: Type = Type::new_extension(ERROR_CUSTOM_TYPE);
146145

147146
/// The string name of the error type.
148147
pub const ERROR_TYPE_NAME: SmolStr = SmolStr::new_inline("error");
@@ -191,6 +190,48 @@ impl KnownTypeConst for ConstUsize {
191190
const TYPE: CustomType = USIZE_CUSTOM_T;
192191
}
193192

193+
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
194+
/// Structure for holding constant usize values.
195+
pub struct ConstError {
196+
/// Integer tag/signal for the error.
197+
pub signal: u32,
198+
/// Error message.
199+
pub message: String,
200+
}
201+
202+
impl ConstError {
203+
/// Define a new error value.
204+
pub fn new(signal: u32, message: impl ToString) -> Self {
205+
Self {
206+
signal,
207+
message: message.to_string(),
208+
}
209+
}
210+
}
211+
212+
#[typetag::serde]
213+
impl CustomConst for ConstError {
214+
fn name(&self) -> SmolStr {
215+
format!("ConstError({:?}, {:?})", self.signal, self.message).into()
216+
}
217+
218+
fn check_custom_type(&self, typ: &CustomType) -> Result<(), CustomCheckFailure> {
219+
self.check_known_type(typ)
220+
}
221+
222+
fn equal_consts(&self, other: &dyn CustomConst) -> bool {
223+
crate::values::downcast_equal_consts(self, other)
224+
}
225+
226+
fn extension_reqs(&self) -> ExtensionSet {
227+
ExtensionSet::singleton(&PRELUDE_ID)
228+
}
229+
}
230+
231+
impl KnownTypeConst for ConstError {
232+
const TYPE: CustomType = ERROR_CUSTOM_TYPE;
233+
}
234+
194235
#[cfg(test)]
195236
mod test {
196237
use crate::{
@@ -219,7 +260,7 @@ mod test {
219260
}
220261

221262
#[test]
222-
/// Test building a HUGR involving a new_array operation.
263+
/// test the prelude error type.
223264
fn test_error_type() {
224265
let ext_def = PRELUDE
225266
.get_type(&ERROR_TYPE_NAME)
@@ -229,5 +270,18 @@ mod test {
229270

230271
let ext_type = Type::new_extension(ext_def);
231272
assert_eq!(ext_type, ERROR_TYPE);
273+
274+
let error_val = ConstError::new(2, "my message");
275+
276+
assert_eq!(error_val.name(), "ConstError(2, \"my message\")");
277+
278+
assert!(error_val.check_custom_type(&ERROR_CUSTOM_TYPE).is_ok());
279+
280+
assert_eq!(
281+
error_val.extension_reqs(),
282+
ExtensionSet::singleton(&PRELUDE_ID)
283+
);
284+
assert!(error_val.equal_consts(&ConstError::new(2, "my message")));
285+
assert!(!error_val.equal_consts(&ConstError::new(3, "my message")));
232286
}
233287
}

0 commit comments

Comments
 (0)