Skip to main content

hap_ble/
error.rs

1//! The crate-wide error type.
2
3/// Errors from the BLE transport.
4#[derive(Debug, thiserror::Error)]
5#[non_exhaustive]
6pub enum BleError {
7    /// Malformed TLV8 in a PDU body or pairing message.
8    #[error("TLV8 error: {0}")]
9    Tlv8(#[from] hap_tlv8::Tlv8Error),
10    /// A pairing or AEAD crypto operation failed.
11    #[error("crypto error: {0}")]
12    Crypto(#[from] hap_crypto::CryptoError),
13    /// The accessory attribute model could not be built or coerced.
14    #[error("model error: {0}")]
15    Model(#[from] hap_model::ModelError),
16    /// No accessory matched the discovery filter.
17    #[error("accessory not found")]
18    AccessoryNotFound,
19    /// The requested characteristic is not in the accessory's database.
20    #[error("characteristic (aid={aid}, iid={iid}) not found")]
21    CharacteristicNotFound {
22        /// Accessory instance id.
23        aid: u64,
24        /// Characteristic instance id.
25        iid: u64,
26    },
27    /// A received HAP-BLE PDU was malformed.
28    #[error("malformed HAP-BLE PDU: {0}")]
29    MalformedPdu(&'static str),
30    /// The accessory rejected a pairing step with a non-zero status.
31    #[error("accessory rejected pairing (status {0})")]
32    PairingRejected(u8),
33    /// The BLE link dropped mid-operation.
34    #[error("the accessory disconnected")]
35    Disconnected,
36    /// An error from the BLE backend (transport-library specific).
37    #[error("BLE backend error: {0}")]
38    Backend(String),
39}
40
41/// The crate result alias.
42pub type Result<T> = core::result::Result<T, BleError>;
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn tlv8_error_converts_via_from() {
50        // A lower-crate error must convert into BleError through `?`.
51        fn inner() -> Result<()> {
52            let _ = hap_tlv8::Tlv8Map::parse(&[0x01])?; // truncated TLV -> Tlv8Error
53            Ok(())
54        }
55        #[allow(clippy::unwrap_used)] // test code: error path is the whole point
56        let err = inner().unwrap_err();
57        assert!(matches!(err, BleError::Tlv8(_)));
58    }
59
60    #[test]
61    fn char_not_found_displays_ids() {
62        let e = BleError::CharacteristicNotFound { aid: 1, iid: 9 };
63        assert_eq!(e.to_string(), "characteristic (aid=1, iid=9) not found");
64    }
65}