1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
use petgraph::stable_graph::NodeIndex;
use static_assertions::const_assert;
use crate::{EdgeInfo, OutputType};
/**
* The name of an [`Operation`](crate::Operation)
*/
pub type OpName = String;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
/**
* Represents an error that can occur in this crate.
*/
pub enum Error {
/**
* The given [`FheProgram`](crate::FheProgram) has
* one or more errors. The inner value is the list of errors.
*/
#[error("The following errors occurred: {0:#?}")]
IRError(Box<Vec<IRError>>),
/**
* Attempted to deserialize and unknown scheme type.
*/
#[error("Attempted to deserialize and unknown scheme type.")]
InvalidSchemeType,
}
const_assert!(std::mem::size_of::<Error>() <= 16);
impl Error {
/**
* Creates an [`Error::IRError`].
*/
pub fn ir_error(inner: &[IRError]) -> Self {
Self::IRError(Box::new(inner.to_owned()))
}
}
/**
* An error in an [`FheProgram`](crate::FheProgram).
*/
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum IRError {
/**
* The IR has a cycle.
*/
IRHasCycles,
/**
* A node in the IR has an error.
*/
NodeError(Box<(NodeIndex, OpName, NodeError)>),
}
impl std::fmt::Display for IRError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::IRHasCycles => {
write!(f, "This FHE program has one or more cycles")
}
Self::NodeError(x) => {
write!(
f,
"Node {}:{} encountered an error: {}",
x.1,
x.0.index(),
x.2
)
}
}
}
}
impl IRError {
/**
* Creates an [`IRError::NodeError`].
*/
pub fn node_error(node_id: NodeIndex, op: OpName, inner: NodeError) -> Self {
Self::NodeError(Box::new((node_id, op, inner)))
}
}
const_assert!(std::mem::size_of::<IRError>() <= 16);
/**
* An error on a node in an [`FheProgram`](crate::FheProgram).
*/
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum NodeError {
/**
* The node is missing an expected operand of the contained type.
*/
MissingOperand(EdgeInfo),
/**
* The parent node specified at the given [`EdgeInfo`] does not exist.
*/
MissingParent(NodeIndex),
/**
* For the parent at EdgeInfo (first argument), the expected
* output type (second argument) does not match the actual
* (third argument) output type.
*/
ParentHasIncorrectOutputType(Box<(EdgeInfo, OutputType, OutputType)>),
/**
* The node has expects a specific number of input operands (first argument),
* but got some other number (second argument).
*/
WrongOperandCount(Box<(usize, usize)>),
}
impl std::fmt::Display for NodeError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingOperand(e) => {
write!(f, "This node is missing operand of type {e:#?}")
}
Self::MissingParent(idx) => {
write!(f, "This node is missing a parent at index {}", idx.index())
}
Self::ParentHasIncorrectOutputType(x) => {
write!(
f,
"For the {:#?} operand, expected an output of {:#?} but found {:#?}.",
x.0, x.1, x.2
)
}
Self::WrongOperandCount(x) => {
write!(
f,
"Incorrect operand count. Expected {}. Found {}.",
x.0, x.1
)
}
}
}
}
impl NodeError {
/**
* Creates a [`NodeError::ParentHasIncorrectOutputType`].
*/
pub fn parent_has_incorrect_output_type(
edge: EdgeInfo,
expected: OutputType,
actual: OutputType,
) -> Self {
Self::ParentHasIncorrectOutputType(Box::new((edge, expected, actual)))
}
/**
* Creates a [`NodeError::WrongOperandCount`].
*/
pub fn wrong_operand_count(expected: usize, actual: usize) -> Self {
Self::WrongOperandCount(Box::new((expected, actual)))
}
}
const_assert!(std::mem::size_of::<NodeError>() <= 16);
/**
* Wrapper around [`Result`](std::result::Result) with this crate's error type.
*/
pub type Result<T> = std::result::Result<T, Error>;