Skip to main content

frp_loom/
error.rs

1use thiserror::Error;
2
3/// Errors returned by [`AtomStore`](crate::store::AtomStore),
4/// [`BlockStore`](crate::store::BlockStore), and
5/// [`EdgeStore`](crate::store::EdgeStore) implementations.
6#[derive(Debug, Error)]
7pub enum StoreError {
8    /// An entity with the given ID could not be found.
9    #[error("not found: {id}")]
10    NotFound { id: String },
11
12    /// A write was rejected due to a duplicate key or failed optimistic
13    /// concurrency check.
14    #[error("conflict on {id}: {reason}")]
15    Conflict { id: String, reason: String },
16
17    /// An I/O or serialization failure occurred.
18    #[error("io error: {0}")]
19    Io(String),
20
21    /// The supplied [`Query`](crate::query::Query) was malformed.
22    #[error("invalid query: {0}")]
23    InvalidQuery(String),
24}
25
26impl StoreError {
27    /// Convenience constructor for `NotFound`.
28    pub fn not_found(id: impl std::fmt::Display) -> Self {
29        Self::NotFound { id: id.to_string() }
30    }
31
32    /// Convenience constructor for `Conflict`.
33    pub fn conflict(id: impl std::fmt::Display, reason: impl Into<String>) -> Self {
34        Self::Conflict { id: id.to_string(), reason: reason.into() }
35    }
36
37    /// Convenience constructor for `Io`.
38    pub fn io(msg: impl Into<String>) -> Self {
39        Self::Io(msg.into())
40    }
41
42    /// Convenience constructor for `InvalidQuery`.
43    pub fn invalid_query(msg: impl Into<String>) -> Self {
44        Self::InvalidQuery(msg.into())
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    #[test]
53    fn not_found_display() {
54        let e = StoreError::not_found("atom-42");
55        assert_eq!(e.to_string(), "not found: atom-42");
56    }
57
58    #[test]
59    fn conflict_display() {
60        let e = StoreError::conflict("block-1", "duplicate key");
61        assert_eq!(e.to_string(), "conflict on block-1: duplicate key");
62    }
63}