Skip to main content

hap_model/
error.rs

1//! Error type for `hap-model`.
2//!
3//! [`ModelError`] covers every failure mode of the parsers and request
4//! builders. Use the crate [`Result`] alias for return types.
5
6use thiserror::Error;
7
8/// All errors `hap-model` can produce.
9#[derive(Debug, Error)]
10#[non_exhaustive]
11pub enum ModelError {
12    /// The input was not valid JSON, or did not match the expected HAP shape.
13    #[error("invalid /accessories or /characteristics JSON: {0}")]
14    Json(#[from] serde_json::Error),
15
16    /// A characteristic declared a `format` string this crate does not know.
17    #[error("unknown characteristic format {0:?}")]
18    UnknownFormat(String),
19
20    /// A type string was neither a short HAP UUID nor a full 36-char UUID.
21    #[error("malformed type UUID {0:?}")]
22    MalformedUuid(String),
23
24    /// A JSON value's type did not match the characteristic's declared format
25    /// (e.g. a string where a number was required).
26    #[error("value type mismatch for format {format}: {detail}")]
27    ValueType {
28        /// The declared characteristic format.
29        format: &'static str,
30        /// What was actually seen.
31        detail: String,
32    },
33
34    /// A numeric value did not fit the declared format's range.
35    #[error("value {value} out of range for format {format}")]
36    ValueRange {
37        /// The declared characteristic format.
38        format: &'static str,
39        /// The offending value, rendered for the message.
40        value: String,
41    },
42
43    /// A `tlv8` / `data` value was not valid base64.
44    #[error("invalid base64 in tlv8/data value: {0}")]
45    Base64(String),
46
47    /// A `/characteristics` response carried a non-zero HAP status code for
48    /// the identified characteristic.
49    #[error("characteristic {aid}.{iid} returned HAP status {status}")]
50    CharacteristicStatus {
51        /// Accessory instance id.
52        aid: u64,
53        /// Characteristic instance id.
54        iid: u64,
55        /// The HAP status code (0 = success; non-zero variants per the spec).
56        status: i64,
57    },
58
59    /// The request executor (in [`crate::AccessoryDatabase`]) failed.
60    #[error("request execution failed: {0}")]
61    Executor(String),
62}
63
64impl ModelError {
65    /// The named HAP status if this is a per-characteristic status error.
66    #[must_use]
67    pub fn hap_status(&self) -> Option<crate::status::HapStatus> {
68        match self {
69            ModelError::CharacteristicStatus { status, .. } => {
70                Some(crate::status::HapStatus::from_code(*status))
71            }
72            _ => None,
73        }
74    }
75}
76
77/// `Result<T, ModelError>` for convenience.
78pub type Result<T> = core::result::Result<T, ModelError>;