Skip to main content

dope_runtime/topology/
error.rs

1use std::convert::Infallible;
2
3use dope_core::driver::life::{domain, domain::Rejected};
4
5use crate::executor::{create, drive, session};
6
7/// Startup and teardown failures without formatting retained operation or output owners.
8#[derive(Debug)]
9pub enum Cause<'a, S> {
10    Runtime(create::Kind<'a>),
11    Storage(&'a S),
12    Close {
13        storage: Option<&'a S>,
14        failure: domain::Unmap,
15    },
16}
17
18impl<'a, S> Cause<'a, S> {
19    pub(super) fn closing<O, T, Q>(state: &'a domain::Closing<'_, Rejected<S, O>, T, Q>) -> Self {
20        Self::Close {
21            storage: state.result().as_ref().err().map(|error| &error.cause),
22            failure: state.failure(),
23        }
24    }
25}
26
27/// Exact application failures without formatting retained successful output.
28#[derive(Debug)]
29pub enum Failure<'a, I> {
30    Run {
31        cause: session::Cause<'a>,
32        output: Option<&'a drive::Error>,
33    },
34    Install(&'a I),
35}
36
37/// Exact execution and teardown failures while their original owners remain retained.
38#[derive(Debug)]
39pub enum Run<'a, S, I> {
40    Runtime(create::Kind<'a>),
41    Storage(&'a S),
42    Failure(Failure<'a, I>),
43    Close {
44        result: Result<Result<(), Failure<'a, I>>, &'a S>,
45        failure: domain::Unmap,
46    },
47}
48
49/// Exact startup or teardown causes borrowed without requiring retained owners to format.
50#[derive(Debug)]
51pub enum Kind<'a, S, T, F = Infallible> {
52    Runtime(create::Kind<'a>),
53    Storage(&'a S),
54    Run(&'a F),
55    Close {
56        result: Result<T, &'a S>,
57        failure: domain::Unmap,
58    },
59}
60
61impl<'a, S, O, T, Q> From<&'a domain::Error<'_, Rejected<S, O>, T, Q>> for Kind<'a, S, &'a T> {
62    fn from(error: &'a domain::Error<'_, Rejected<S, O>, T, Q>) -> Self {
63        match error {
64            domain::Error::Storage(error) => Self::Storage(&error.cause),
65            domain::Error::Close(state) => Self::closing(state),
66        }
67    }
68}
69
70impl<'a, S, T, F> Kind<'a, S, &'a T, F> {
71    pub(super) fn closing<O, Q>(state: &'a domain::Closing<'_, Rejected<S, O>, T, Q>) -> Self {
72        Self::Close {
73            result: state.result().as_ref().map_err(|error| &error.cause),
74            failure: state.failure(),
75        }
76    }
77}
78
79impl<'a, S, T, F> Kind<'a, S, T, F> {
80    pub fn map<U>(self, map: impl FnOnce(T) -> U) -> Kind<'a, S, U, F> {
81        match self {
82            Self::Runtime(error) => Kind::Runtime(error),
83            Self::Storage(error) => Kind::Storage(error),
84            Self::Run(error) => Kind::Run(error),
85            Self::Close { result, failure } => Kind::Close {
86                result: result.map(map),
87                failure,
88            },
89        }
90    }
91}