elemaudio_rs/
error.rs

1//! Error types and native return-code mapping for the runtime wrapper.
2
3use std::ffi::NulError;
4use std::fmt::{Display, Formatter};
5
6/// Result type used by the public API.
7pub type Result<T> = std::result::Result<T, Error>;
8
9/// Errors returned by the safe wrapper.
10#[derive(Debug)]
11pub enum Error {
12    /// The native runtime returned a null handle during construction.
13    NullHandle,
14    /// A wrapper-side argument validation failure.
15    InvalidArgument(&'static str),
16    /// A string contained an interior nul byte before crossing the FFI boundary.
17    CString(NulError),
18    /// A native operation returned a non-zero status code.
19    Native {
20        /// The operation that failed.
21        operation: &'static str,
22        /// The raw native status code.
23        code: i32,
24        /// Human-readable description of the status code.
25        message: String,
26    },
27    /// A resource with the given id already exists.
28    ResourceExists(String),
29    /// A resource with the given id could not be found.
30    ResourceNotFound(String),
31    /// A resource exists but does not match the requested type.
32    ResourceTypeMismatch {
33        /// Resource identifier.
34        id: String,
35        /// Expected kind.
36        expected: &'static str,
37        /// Actual kind.
38        actual: &'static str,
39    },
40}
41
42impl Display for Error {
43    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
44        match self {
45            Self::NullHandle => write!(f, "native runtime handle was null"),
46            Self::InvalidArgument(message) => write!(f, "invalid argument: {message}"),
47            Self::CString(err) => write!(f, "string contains interior nul byte: {err}"),
48            Self::Native {
49                operation,
50                code,
51                message,
52            } => {
53                write!(f, "{operation} failed with code {code}: {message}")
54            }
55            Self::ResourceExists(id) => write!(f, "resource already exists: {id}"),
56            Self::ResourceNotFound(id) => write!(f, "resource not found: {id}"),
57            Self::ResourceTypeMismatch {
58                id,
59                expected,
60                actual,
61            } => {
62                write!(f, "resource {id} has kind {actual}, expected {expected}")
63            }
64        }
65    }
66}
67
68impl std::error::Error for Error {}
69
70impl From<NulError> for Error {
71    fn from(value: NulError) -> Self {
72        Self::CString(value)
73    }
74}
75
76/// Describes a native runtime return code.
77///
78/// The mapping is used when the native bridge reports a failure code and the
79/// wrapper needs to surface a human-readable message.
80pub fn describe_return_code(code: i32) -> &'static str {
81    match code {
82        0 => "Ok",
83        1 => "Node type not recognized: the requested node kind was not registered in the runtime bridge",
84        2 => "Node not found",
85        3 => "Attempting to create a node that already exists",
86        4 => "Attempting to create a node type that already exists",
87        5 => "Invalid value type for the given node property",
88        6 => "Invalid value for the given node property",
89        7 => "Invariant violation",
90        8 => "Invalid instruction format",
91        _ => "Return code not recognized",
92    }
93}