Skip to main content

sim_lib_expr_tree_server/
error.rs

1//! Structured expression-tree server errors.
2
3use std::fmt;
4
5use sim_kernel::{Error, Expr, Symbol};
6use sim_value::build;
7
8/// Stable structured error returned by the expression-tree server.
9#[derive(Clone, Debug, Eq, PartialEq)]
10pub struct ExpressionTreeServerError {
11    code: &'static str,
12    message: String,
13}
14
15impl ExpressionTreeServerError {
16    pub(crate) fn new(code: &'static str, message: impl Into<String>) -> Self {
17        let message = message.into();
18        let message = message.chars().take(512).collect();
19        Self { code, message }
20    }
21
22    /// Returns the stable machine-readable error code.
23    pub const fn code(&self) -> &'static str {
24        self.code
25    }
26
27    /// Returns the bounded human-readable message.
28    pub fn message(&self) -> &str {
29        &self.message
30    }
31
32    /// Projects the error into the open remote-error map understood by standard
33    /// server-backed surface transports.
34    pub fn to_expr(&self) -> Expr {
35        build::map(vec![
36            (
37                "error",
38                Expr::Symbol(Symbol::qualified("expr-tree-server", self.code)),
39            ),
40            ("message", build::text(&self.message)),
41        ])
42    }
43}
44
45impl fmt::Display for ExpressionTreeServerError {
46    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
47        write!(
48            formatter,
49            "expr-tree-server/{}: {}",
50            self.code, self.message
51        )
52    }
53}
54
55impl std::error::Error for ExpressionTreeServerError {}
56
57impl From<ExpressionTreeServerError> for Error {
58    fn from(error: ExpressionTreeServerError) -> Self {
59        Self::HostError(error.to_string())
60    }
61}
62
63pub(crate) type ServerResult<T> = std::result::Result<T, ExpressionTreeServerError>;
64
65pub(crate) fn internal(error: impl fmt::Display) -> ExpressionTreeServerError {
66    ExpressionTreeServerError::new("internal", error.to_string())
67}