Skip to main content

trellis_runner/engine/
result.rs

1use crate::result::{EngineOutput, EngineOutputWithSnapshot};
2use crate::state::{State, UserState};
3use crate::TrellisFloat;
4
5/// Unified result type returned by the engine.
6///
7/// This captures both:
8/// - successful execution paths (`EngineEngineOutput`)
9/// - exceptional failure paths (`EngineFailure`)
10///
11/// The separation is intentional:
12/// - `EngineSuccess` = controlled, expected termination
13/// - `EngineFailure` = unexpected error during execution
14pub type EngineResult<O, S, E> = Result<EngineOutput<O, S>, EngineFailure<S, E>>;
15
16pub(super) type InternalEngineResult<O, S, E> =
17    Result<EngineOutput<O, S>, InternalEngineFailure<E>>;
18
19pub type EngineResultWithSnapshot<O, S, E> =
20    Result<EngineOutputWithSnapshot<O, S>, EngineFailure<S, E>>;
21
22#[derive(thiserror::Error, Debug)]
23pub enum EngineFailure<S, E>
24where
25    S: UserState,
26    <S as UserState>::Float: TrellisFloat,
27{
28    /// A failure originating from the user-defined procedure.
29    ///
30    /// This represents an *exceptional error path*, not a normal termination.
31    /// It indicates that the solver logic itself could not complete a step
32    /// or finalisation phase.
33    ///
34    /// The included `State` is a snapshot of the engine at the point of failure
35    /// and can be used for debugging or checkpoint recovery.
36    #[error("error in underlying procedure: {error}")]
37    Procedure {
38        /// The underlying procedure error.
39        error: E,
40
41        /// Snapshot of the solver state at the time of failure.
42        state: State<S>,
43    },
44}
45
46impl<S, E> EngineFailure<S, E>
47where
48    S: UserState,
49    <S as UserState>::Float: TrellisFloat,
50{
51    pub(super) fn from_internal(internal: InternalEngineFailure<E>, state: State<S>) -> Self {
52        EngineFailure::Procedure {
53            error: internal.0,
54            state,
55        }
56    }
57}
58
59pub(super) struct InternalEngineFailure<E>(E);
60
61impl<E> InternalEngineFailure<E> {
62    pub(super) fn new(error: E) -> Self {
63        Self(error)
64    }
65}