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
use std::fmt; use crate::Status; /// Trait alias for types that programmatically specify the status. /// /// For prototyping, see [`Unkind`]. /// /// # Example /// /// ```rust /// use status::Kind; /// /// #[derive(Copy, Clone, Debug, derive_more::Display)] /// enum ErrorKind { /// #[display(fmt = "Failed to read file")] /// Read, /// #[display(fmt = "Failed to parse")] /// Parse, /// } /// type Status = status::Status<ErrorKind>; /// type Result<T, E = Status> = std::result::Result<T, E>; /// /// fn read_file() -> Result<()> { /// return ErrorKind::Read.into_err(); /// } /// ``` pub trait Kind: Copy + Clone + fmt::Display + fmt::Debug + Send + Sync + 'static { /// Convenience for creating an error. fn into_status<C: crate::Context>(self) -> Status<Self, C> { Status::new(self) } /// Convenience for returning an error. fn into_err<T, C: crate::Context>(self) -> Result<T, Status<Self, C>> { Err(Status::new(self)) } } impl<U> Kind for U where U: Copy + Clone + fmt::Display + fmt::Debug + Send + Sync + 'static {} /// Adhoc [`Kind`]. /// /// Unlike most [`Kind`]s, this is meant to be opaque and not programmatically specify the status. /// It is only good for displaying a `str` to the user when prototyping before one transitions to more formal [`Kind`]s. /// /// Note: This is the default [`Kind`] for [`Status`]. /// /// When transitioning to a more useful [`Kind`], it could be helpful to have an `enum` variant /// with an `Unkind`: /// ``` /// #[derive(Copy, Clone, Debug, derive_more::Display)] /// enum ErrorKind { /// #[display(fmt = "Failed to read file")] /// Read, /// #[display(fmt = "Failed to parse")] /// Parse, /// #[display(fmt = "{}", "_0")] /// Other(status::Unkind), /// } /// ``` #[derive(Copy, Clone, Debug)] pub struct Unkind { inner: &'static str, } impl From<&'static str> for Unkind { fn from(s: &'static str) -> Self { Self { inner: s } } } impl fmt::Display for Unkind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "{}", self.inner) } } #[cfg(test)] mod test { use super::*; use static_assertions::*; #[test] fn unkind() { assert_impl_all!(Unkind: Kind); } }