diff --git a/src/extension/op_def.rs b/src/extension/op_def.rs index 74f47178e..e800754f4 100644 --- a/src/extension/op_def.rs +++ b/src/extension/op_def.rs @@ -441,7 +441,7 @@ impl Extension { &mut self, op: &(impl super::simple_op::OpEnum + OpName), ) -> Result<&mut OpDef, ExtensionBuildError> { - let def = self.add_op(op.name(), op.description().to_string(), op.def_signature())?; + let def = self.add_op(op.name(), op.description(), op.def_signature())?; op.post_opdef(def); diff --git a/src/extension/simple_op.rs b/src/extension/simple_op.rs index b7aa89fa8..474cf2a50 100644 --- a/src/extension/simple_op.rs +++ b/src/extension/simple_op.rs @@ -15,20 +15,12 @@ use super::{ }; use delegate::delegate; use thiserror::Error; -/// Error when definition extension does not match that of the [OpEnum] -#[derive(Debug, Error, PartialEq)] -#[error("Expected extension ID {expected} but found {provided}.")] -pub struct WrongExtension { - expected: ExtensionId, - provided: ExtensionId, -} /// Error loading [OpEnum] #[derive(Debug, Error, PartialEq)] #[error("{0}")] #[allow(missing_docs)] pub enum OpLoadError { - WrongExtension(#[from] WrongExtension), #[error("Op with name {0} is not a member of this enum.")] NotEnumMember(String), #[error("Type args invalid: {0}.")] @@ -48,14 +40,18 @@ where /// to simplify interactions with the extension. /// Relies on `strum_macros::{EnumIter, EnumString, IntoStaticStr}` pub trait OpEnum: OpName { - /// Description type. - type Description: ToString; + /// Try to load one of the operations of this set from an [OpDef]. + fn from_op_def(op_def: &OpDef, args: &[TypeArg]) -> Result + where + Self: Sized; /// Return the signature (polymorphic function type) of the operation. fn def_signature(&self) -> SignatureFunc; - /// Description of the operation. - fn description(&self) -> Self::Description; + /// Description of the operation. By default, the same as `self.name()`. + fn description(&self) -> String { + self.name().to_string() + } /// Any type args which define this operation. Default is no type arguments. fn type_args(&self) -> Vec { @@ -65,11 +61,6 @@ pub trait OpEnum: OpName { /// Edit the opdef before finalising. By default does nothing. fn post_opdef(&self, _def: &mut OpDef) {} - /// Try to load one of the operations of this set from an [OpDef]. - fn from_op_def(op_def: &OpDef, args: &[TypeArg]) -> Result - where - Self: Sized; - /// Try to instantiate a variant from an [OpType]. Default behaviour assumes /// an [ExtensionOp] and loads from the name. fn from_optype(op: &OpType) -> Option @@ -80,11 +71,11 @@ pub trait OpEnum: OpName { Self::from_op_def(ext.def(), ext.args()).ok() } - fn to_registered<'r>( + fn to_registered( self, extension_id: ExtensionId, - registry: &'r ExtensionRegistry, - ) -> RegisteredEnum<'r, Self> + registry: &ExtensionRegistry, + ) -> RegisteredEnum<'_, Self> where Self: Sized, { @@ -137,7 +128,14 @@ pub struct RegisteredEnum<'r, T> { op_enum: T, } -impl<'a, T: OpEnum> RegisteredEnum<'a, T> { +impl RegisteredEnum<'_, T> { + /// Extract the inner wrapped value + pub fn to_inner(self) -> T { + self.op_enum + } +} + +impl RegisteredEnum<'_, T> { /// Generate an [OpType]. pub fn to_optype(&self) -> Option { let leaf: LeafOp = ExtensionOp::new( @@ -166,6 +164,7 @@ impl<'a, T: OpEnum> RegisteredEnum<'a, T> { self.registry, ) } + delegate! { to self.op_enum { /// Name of the operation - derived from strum serialization. @@ -173,7 +172,7 @@ impl<'a, T: OpEnum> RegisteredEnum<'a, T> { /// Any type args which define this operation. Default is no type arguments. pub fn type_args(&self) -> Vec; /// Description of the operation. - pub fn description(&self) -> T::Description; + pub fn description(&self) -> String; } } } @@ -188,20 +187,12 @@ mod test { enum DummyEnum { Dumb, } - #[derive(Debug, thiserror::Error, PartialEq)] - #[error("Dummy")] - struct DummyError; - impl OpEnum for DummyEnum { - type Description = &'static str; + impl OpEnum for DummyEnum { fn def_signature(&self) -> SignatureFunc { FunctionType::new_endo(type_row![]).into() } - fn description(&self) -> Self::Description { - "dummy" - } - fn from_op_def(_op_def: &OpDef, _args: &[TypeArg]) -> Result { Ok(Self::Dumb) } @@ -221,18 +212,19 @@ mod test { o ); + let registry = ExtensionRegistry::try_new([e.to_owned()]).unwrap(); + let registered = o.clone().to_registered(ext_name, ®istry); assert_eq!( - DummyEnum::from_optype( - &o.clone() - .to_registered( - ext_name, - &ExtensionRegistry::try_new([e.to_owned()]).unwrap() - ) - .to_optype() - .unwrap() - ) - .unwrap(), + DummyEnum::from_optype(®istered.to_optype().unwrap()).unwrap(), o ); + assert_eq!( + registered.function_type().unwrap(), + FunctionType::new_endo(type_row![]) + ); + + assert_eq!(registered.description(), "Dumb"); + + assert_eq!(registered.to_inner(), o); } } diff --git a/src/std_extensions/logic.rs b/src/std_extensions/logic.rs index 368060ca4..1d9d78630 100644 --- a/src/std_extensions/logic.rs +++ b/src/std_extensions/logic.rs @@ -31,8 +31,6 @@ pub enum LogicOp { } impl OpEnum for LogicOp { - type Description = &'static str; - fn from_op_def(op_def: &OpDef, args: &[TypeArg]) -> Result { let mut out: LogicOp = try_from_name(op_def.name())?; match &mut out { @@ -55,12 +53,13 @@ impl OpEnum for LogicOp { } } - fn description(&self) -> &'static str { + fn description(&self) -> String { match self { LogicOp::And(_) => "logical 'and'", LogicOp::Or(_) => "logical 'or'", LogicOp::Not => "logical 'not'", } + .to_string() } fn type_args(&self) -> Vec { match self {