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> = Result<EngineOutput<O, S>, EngineFailure<S>>;
15
16pub(super) type InternalEngineResult<O, S> = Result<EngineOutput<O, S>, InternalEngineFailure>;
17
18pub type EngineResultWithSnapshot<O, S> = Result<EngineOutputWithSnapshot<O, S>, EngineFailure<S>>;
19
20#[derive(thiserror::Error, Debug)]
21pub enum EngineFailure<S>
22where
23    S: UserState,
24    <S as UserState>::Float: TrellisFloat,
25{
26    /// A failure originating from the user-defined procedure.
27    ///
28    /// This represents an *exceptional error path*, not a normal termination.
29    /// It indicates that the solver logic itself could not complete a step
30    /// or finalisation phase.
31    ///
32    /// The included `State` is a snapshot of the engine at the point of failure
33    /// and can be used for debugging or checkpoint recovery.
34    #[error("error in underlying procedure: {error}")]
35    Procedure {
36        /// The underlying procedure error.
37        error: Box<dyn std::error::Error + Send + Sync>,
38
39        /// Snapshot of the solver state at the time of failure.
40        state: State<S>,
41    },
42}
43
44impl<S> EngineFailure<S>
45where
46    S: UserState,
47    <S as UserState>::Float: TrellisFloat,
48{
49    pub(super) fn from_internal(internal: InternalEngineFailure, state: State<S>) -> Self {
50        EngineFailure::Procedure {
51            error: internal.0,
52            state,
53        }
54    }
55}
56
57pub(super) struct InternalEngineFailure(Box<dyn std::error::Error + Send + Sync>);
58
59impl InternalEngineFailure {
60    pub(super) fn new<E>(error: E) -> Self
61    where
62        E: std::error::Error + Send + Sync + 'static,
63    {
64        Self(Box::new(error))
65    }
66}