Skip to main content

fast_mesh_store/
error.rs

1use std::fmt;
2
3/// Errors returned by mesh storage operations.
4///
5/// Validation errors are returned before anything is written, so a transaction
6/// stays usable after one. `TransactionPoisoned` and `OutOfMemory` are the exceptions.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum StoreError {
9    /// The vertex id is out of range or refers to a removed vertex.
10    InvalidVertex(u32),
11    /// The triangle id is out of range or refers to a removed triangle.
12    InvalidTriangle(u32),
13    /// The vertex cannot be removed while triangles still use it.
14    VertexInUse { vertex: u32, corners: u32 },
15    /// Two related inputs have inconsistent lengths.
16    LengthMismatch { expected: usize, got: usize },
17    /// An argument is invalid; the message says which and why.
18    InvalidArgument(&'static str),
19    /// No channel with this name exists.
20    UnknownChannel(String),
21    /// A channel with this name already exists.
22    ChannelExists(String),
23    /// The operation needs a source channel.
24    NotSourceChannel(String),
25    /// The operation needs a derived channel.
26    NotDerivedChannel(String),
27    /// The patch belongs to another mesh or does not match the mesh's current revision.
28    PatchMismatch,
29    /// The patch was created before `compact()` renumbered the mesh.
30    StalePatch,
31    /// An earlier operation in this transaction failed after writing; the transaction was rolled back.
32    TransactionPoisoned,
33    /// A memory allocation failed.
34    OutOfMemory,
35}
36
37impl fmt::Display for StoreError {
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        match self {
40            Self::InvalidVertex(v) => write!(f, "vertex {v} does not exist"),
41            Self::InvalidTriangle(t) => write!(f, "triangle {t} does not exist"),
42            Self::VertexInUse { vertex, corners } => {
43                write!(
44                    f,
45                    "vertex {vertex} is still used by {corners} triangle corners"
46                )
47            }
48            Self::LengthMismatch { expected, got } => {
49                write!(f, "expected length {expected}, got {got}")
50            }
51            Self::InvalidArgument(msg) => write!(f, "invalid argument: {msg}"),
52            Self::UnknownChannel(name) => write!(f, "channel \"{name}\" does not exist"),
53            Self::ChannelExists(name) => write!(f, "channel \"{name}\" already exists"),
54            Self::NotSourceChannel(name) => write!(f, "channel \"{name}\" is not a source channel"),
55            Self::NotDerivedChannel(name) => {
56                write!(f, "channel \"{name}\" is not a derived channel")
57            }
58            Self::PatchMismatch => write!(f, "patch does not match this mesh's current revision"),
59            Self::StalePatch => write!(f, "patch was created before the mesh was compacted"),
60            Self::TransactionPoisoned => {
61                write!(
62                    f,
63                    "transaction was rolled back because an earlier operation failed"
64                )
65            }
66            Self::OutOfMemory => write!(f, "out of memory"),
67        }
68    }
69}
70
71impl std::error::Error for StoreError {}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn messages_name_the_problem() {
79        assert_eq!(
80            StoreError::InvalidVertex(7).to_string(),
81            "vertex 7 does not exist"
82        );
83        assert_eq!(
84            StoreError::VertexInUse {
85                vertex: 3,
86                corners: 2
87            }
88            .to_string(),
89            "vertex 3 is still used by 2 triangle corners"
90        );
91        assert_eq!(
92            StoreError::UnknownChannel("mask".into()).to_string(),
93            "channel \"mask\" does not exist"
94        );
95    }
96}