1use crate::{State, UserState};
5use num_traits::float::FloatCore;
6use std::fmt;
7
8pub type CalculationResult<O, S, E> = Result<Output<O, S>, TrellisError<O, E>>;
10
11pub struct Output<R, S>
18where
19 S: UserState,
20{
21 pub result: R,
23 pub state: State<S>,
25}
26
27impl<R, S> std::fmt::Display for Output<R, S>
28where
29 R: fmt::Display,
30 S: UserState,
31 <S as UserState>::Float: FloatCore,
32{
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 if let Some(cause) = self.state.termination_cause() {
35 use crate::Cause::*;
36 match cause {
37 Converged => {
38 writeln!(
39 f,
40 "Solver converged after {} iterations",
41 self.state.current_iteration()
42 )?;
43 if let Some(duration) = self.state.duration() {
44 writeln!(f, "Duration {:?}", duration)?;
45 }
46 writeln!(f, "{}", self.result)?;
47 }
48 ControlC => {
49 writeln!(
50 f,
51 "Solver converged by ctrl-c intervention after {} iterations",
52 self.state.current_iteration()
53 )?;
54 }
55 Parent => {
56 writeln!(
57 f,
58 "Solver converged by parent intervention after {} iterations",
59 self.state.current_iteration()
60 )?;
61 }
62 ExceededMaxIterations => {
63 writeln!(
64 f,
65 "Solver exceeded maximum iterations ({})",
66 self.state.current_iteration()
67 )?;
68 }
69 }
70 } else {
71 writeln!(f, "Solver is still in progress.")?;
72 }
73 Ok(())
74 }
75}
76
77impl<R, S> Output<R, S>
78where
79 S: UserState,
80{
81 pub(crate) fn new(result: R, state: State<S>) -> Self {
82 Self { result, state }
83 }
84}
85
86#[derive(thiserror::Error, Debug)]
87pub struct TrellisError<O, E> {
96 #[source]
97 pub cause: ErrorCause<E>,
99 pub result: Option<O>,
101}
102
103impl<O, E> From<E> for TrellisError<O, E> {
104 fn from(cause: E) -> Self {
105 Self {
106 cause: ErrorCause::User(cause),
107 result: None,
108 }
109 }
110}
111
112impl<O, E: ::std::fmt::Debug> ::std::fmt::Display for TrellisError<O, E> {
113 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114 writeln!(f, "Trellis error: {:?}", self.cause)
115 }
116}
117
118#[derive(thiserror::Error, Debug)]
119pub enum ErrorCause<E> {
120 #[error("error in user defined calculation: {0}")]
121 User(#[from] E),
122 #[error("exceeded maximum number of iterations")]
123 MaxIterExceeded,
124 #[error("calculation cancelled due to ctrl-c")]
125 ControlC,
126 #[error("calculation cancelled due to cancelled token")]
127 CancellationToken,
128}