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
use std::sync::Arc;

use pliantdb_core::schema::{view, InvalidNameError};

/// Errors that can occur from interacting with storage.
#[derive(thiserror::Error, Debug)]
pub enum Error {
    /// An error occurred interacting with `sled`.
    #[error("error from storage: {0}")]
    Sled(#[from] sled::Error),

    /// An error occurred serializing the underlying database structures.
    #[error("error while serializing internal structures: {0}")]
    InternalSerialization(#[from] bincode::Error),

    /// An error occurred serializing the contents of a `Document` or results of a `View`.
    #[error("error while serializing: {0}")]
    Serialization(#[from] serde_cbor::Error),

    /// An internal error occurred while waiting for a message.
    #[error("error while waiting for a message: {0}")]
    InternalCommunication(#[from] flume::RecvError),

    /// An error occurred while executing a view
    #[error("error from view: {0}")]
    View(#[from] view::Error),

    /// An core error occurred.
    #[error("a core error occurred: {0}")]
    Core(#[from] pliantdb_core::Error),

    /// An unexpected error occurred.
    #[error("an unexpected error occurred: {0}")]
    Other(#[from] Arc<anyhow::Error>),
}

impl From<Error> for pliantdb_core::Error {
    fn from(err: Error) -> Self {
        match err {
            Error::Core(core) => core,
            other => Self::Database(other.to_string()),
        }
    }
}

impl From<InvalidNameError> for Error {
    fn from(err: InvalidNameError) -> Self {
        Self::Core(pliantdb_core::Error::from(err))
    }
}

pub trait ResultExt {
    type Output;
    fn map_err_to_core(self) -> Result<Self::Output, pliantdb_core::Error>;
}

impl<T, E> ResultExt for Result<T, E>
where
    E: Into<Error>,
{
    type Output = T;

    fn map_err_to_core(self) -> Result<Self::Output, pliantdb_core::Error> {
        self.map_err(|err| pliantdb_core::Error::Database(err.into().to_string()))
    }
}

#[test]
fn test_converting_error() {
    use serde::ser::Error as _;
    let err: pliantdb_core::Error =
        Error::Serialization(serde_cbor::Error::custom("mymessage")).into();
    match err {
        pliantdb_core::Error::Database(storage_error) => {
            assert!(storage_error.contains("mymessage"))
        }
        _ => unreachable!(),
    }
}