diff --git a/tket2-py/src/circuit.rs b/tket2-py/src/circuit.rs index 674e7cba..931dbe85 100644 --- a/tket2-py/src/circuit.rs +++ b/tket2-py/src/circuit.rs @@ -53,7 +53,7 @@ pub fn module(py: Python<'_>) -> PyResult> { "HUGRSerializationError", py.get_type_bound::(), )?; - m.add("OpConvertError", py.get_type_bound::())?; + m.add("TK1ConvertError", py.get_type_bound::())?; Ok(m) } @@ -83,8 +83,8 @@ create_py_exception!( ); create_py_exception!( - tket2::serialize::pytket::OpConvertError, - PyOpConvertError, + tket2::serialize::pytket::TK1ConvertError, + PyTK1ConvertError, "Error type for the conversion between tket2 and tket1 operations." ); diff --git a/tket2-py/tket2/_tket2/circuit.pyi b/tket2-py/tket2/_tket2/circuit.pyi index 04369814..6c92063e 100644 --- a/tket2-py/tket2/_tket2/circuit.pyi +++ b/tket2-py/tket2/_tket2/circuit.pyi @@ -180,4 +180,4 @@ class HugrError(Exception): ... class BuildError(Exception): ... class ValidationError(Exception): ... class HUGRSerializationError(Exception): ... -class OpConvertError(Exception): ... +class TK1ConvertError(Exception): ... diff --git a/tket2-py/tket2/circuit/__init__.py b/tket2-py/tket2/circuit/__init__.py index ae0d5829..db726e35 100644 --- a/tket2-py/tket2/circuit/__init__.py +++ b/tket2-py/tket2/circuit/__init__.py @@ -15,7 +15,7 @@ BuildError, ValidationError, HUGRSerializationError, - OpConvertError, + TK1ConvertError, ) from .build import CircBuild, Command @@ -39,5 +39,5 @@ "BuildError", "ValidationError", "HUGRSerializationError", - "OpConvertError", + "TK1ConvertError", ] diff --git a/tket2/src/serialize/pytket.rs b/tket2/src/serialize/pytket.rs index 785ed556..89366f2f 100644 --- a/tket2/src/serialize/pytket.rs +++ b/tket2/src/serialize/pytket.rs @@ -4,6 +4,7 @@ mod decoder; mod encoder; mod op; +use hugr::types::Type; pub(crate) use op::JsonOp; #[cfg(test)] @@ -52,8 +53,8 @@ pub trait TKETDecode: Sized { } impl TKETDecode for SerialCircuit { - type DecodeError = OpConvertError; - type EncodeError = OpConvertError; + type DecodeError = TK1ConvertError; + type EncodeError = TK1ConvertError; fn decode(self) -> Result { let mut decoder = JsonDecoder::new(&self); @@ -73,11 +74,12 @@ impl TKETDecode for SerialCircuit { fn encode(circ: &Circuit) -> Result { let mut encoder = JsonEncoder::new(circ); let f64_inputs = circ.units().filter_map(|(wire, _, t)| match (wire, t) { - (CircuitUnit::Wire(wire), t) if t == FLOAT64_TYPE => Some(wire), + (CircuitUnit::Wire(wire), t) if t == FLOAT64_TYPE => Some(Ok(wire)), (CircuitUnit::Linear(_), _) => None, - _ => unimplemented!("Non-float64 input wires not supported"), + (_, typ) => Some(Err(TK1ConvertError::NonSerializableInputs { typ })), }); for (i, wire) in f64_inputs.enumerate() { + let wire = wire?; let param = format!("f{i}"); encoder.add_parameter(wire, param); } @@ -93,14 +95,11 @@ impl TKETDecode for SerialCircuit { #[derive(Debug, Error)] pub enum OpConvertError { /// The serialized operation is not supported. - #[error("Unsupported serialized operation: {0:?}")] + #[error("Unsupported serialized pytket operation: {0:?}")] UnsupportedSerializedOp(JsonOpType), /// The serialized operation is not supported. - #[error("Cannot serialize operation: {0:?}")] + #[error("Cannot serialize tket2 operation: {0:?}")] UnsupportedOpSerialization(OpType), - /// The serialized operation is not supported. - #[error("Cannot serialize operation: {0:?}")] - NonSerializableInputs(OpType), } /// Load a TKET1 circuit from a JSON file. @@ -142,49 +141,30 @@ pub fn save_tk1_json_str(circ: &Circuit) -> Result { let mut buf = io::BufWriter::new(Vec::new()); save_tk1_json_writer(circ, &mut buf)?; let bytes = buf.into_inner().unwrap(); - String::from_utf8(bytes).map_err(|_| TK1ConvertError::InvalidJson) + Ok(String::from_utf8(bytes)?) } /// Error type for conversion between `Op` and `OpType`. #[derive(Debug, Error)] pub enum TK1ConvertError { - /// The serialized operation is not supported. - #[error("unsupported serialized operation: {0:?}")] - UnsupportedSerializedOp(JsonOpType), - /// The serialized operation is not supported. - #[error("cannot serialize operation: {0:?}")] - UnsupportedOpSerialization(OpType), - /// The serialized operation is not supported. - #[error("cannot serialize operation: {0:?}")] - NonSerializableInputs(OpType), + /// Operation conversion error. + #[error("{0}")] + OpConversionError(#[from] OpConvertError), + /// The circuit has non-serializable inputs. + #[error("Circuit contains non-serializable input of type {typ}.")] + NonSerializableInputs { + /// The unsupported type. + typ: Type, + }, + /// Invalid JSON, + #[error("Invalid pytket JSON. {0}")] + InvalidJson(#[from] serde_json::Error), /// Invalid JSON, - #[error("invalid JSON")] - InvalidJson, + #[error("Invalid JSON encoding. {0}")] + InvalidJsonEncoding(#[from] std::string::FromUtf8Error), /// File not found., - #[error("unable to load file")] - FileLoadError, -} - -impl From for TK1ConvertError { - fn from(_: serde_json::Error) -> Self { - Self::InvalidJson - } -} - -impl From for TK1ConvertError { - fn from(_: io::Error) -> Self { - Self::FileLoadError - } -} - -impl From for TK1ConvertError { - fn from(value: OpConvertError) -> Self { - match value { - OpConvertError::UnsupportedSerializedOp(op) => Self::UnsupportedSerializedOp(op), - OpConvertError::UnsupportedOpSerialization(op) => Self::UnsupportedOpSerialization(op), - OpConvertError::NonSerializableInputs(op) => Self::NonSerializableInputs(op), - } - } + #[error("Unable to load pytket json file. {0}")] + FileLoadError(#[from] io::Error), } #[inline]