//! Error type mapping from soliton::error::Error to Python exceptions. use pyo3::create_exception; use pyo3::exceptions::PyException; use pyo3::prelude::*; // Each soliton error variant gets a dedicated Python exception class, // all inheriting from SolitonError. create_exception!( soliton, SolitonError, PyException, "Base exception for all soliton errors." ); create_exception!( soliton, InvalidLengthError, SolitonError, "Wrong-size parameter." ); create_exception!( soliton, InvalidDataError, SolitonError, "Structurally invalid content." ); create_exception!(soliton, AeadError, SolitonError, "AEAD decryption failed."); create_exception!( soliton, VerificationError, SolitonError, "Signature verification failed." ); create_exception!( soliton, BundleVerificationError, SolitonError, "Pre-key bundle verification failed." ); create_exception!( soliton, DecapsulationError, SolitonError, "KEM decapsulation failed." ); create_exception!( soliton, DuplicateMessageError, SolitonError, "Replayed or already-seen message." ); create_exception!( soliton, ChainExhaustedError, SolitonError, "Counter-space exhausted." ); create_exception!( soliton, UnsupportedVersionError, SolitonError, "Unsupported blob version." ); create_exception!( soliton, UnsupportedCryptoVersionError, SolitonError, "Unrecognized crypto version." ); create_exception!( soliton, InternalError, SolitonError, "Internal invariant violated." ); /// Convert a soliton::error::Error into the appropriate Python exception. pub fn to_py_err(e: soliton::error::Error) -> PyErr { use soliton::error::Error; match e { Error::InvalidLength { .. } => InvalidLengthError::new_err(e.to_string()), Error::InvalidData => InvalidDataError::new_err(e.to_string()), Error::AeadFailed => AeadError::new_err(e.to_string()), Error::VerificationFailed => VerificationError::new_err(e.to_string()), Error::BundleVerificationFailed => BundleVerificationError::new_err(e.to_string()), Error::DecapsulationFailed => DecapsulationError::new_err(e.to_string()), Error::DuplicateMessage => DuplicateMessageError::new_err(e.to_string()), Error::ChainExhausted => ChainExhaustedError::new_err(e.to_string()), Error::UnsupportedVersion => UnsupportedVersionError::new_err(e.to_string()), Error::UnsupportedCryptoVersion => UnsupportedCryptoVersionError::new_err(e.to_string()), Error::Internal => InternalError::new_err(e.to_string()), _ => SolitonError::new_err(e.to_string()), } } pub fn register(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add("SolitonError", m.py().get_type::())?; m.add( "InvalidLengthError", m.py().get_type::(), )?; m.add("InvalidDataError", m.py().get_type::())?; m.add("AeadError", m.py().get_type::())?; m.add("VerificationError", m.py().get_type::())?; m.add( "BundleVerificationError", m.py().get_type::(), )?; m.add( "DecapsulationError", m.py().get_type::(), )?; m.add( "DuplicateMessageError", m.py().get_type::(), )?; m.add( "ChainExhaustedError", m.py().get_type::(), )?; m.add( "UnsupportedVersionError", m.py().get_type::(), )?; m.add( "UnsupportedCryptoVersionError", m.py().get_type::(), )?; m.add("InternalError", m.py().get_type::())?; Ok(()) }