bluest 0.6.9

A cross-platform Bluetooth Low Energy (BLE) library
Documentation
use objc2::rc::Retained;
use objc2_core_bluetooth::CBError;
use objc2_foundation::NSError;

use crate::error::{AttError, ErrorKind};

impl crate::Error {
    pub(super) fn from_recv_error(err: async_broadcast::RecvError) -> Self {
        crate::Error::new(ErrorKind::Internal, Some(Box::new(err)), "receiving delegate event")
    }

    pub(super) fn from_nserror(err: Retained<NSError>) -> Self {
        crate::Error::new(
            kind_from_nserror(&err),
            Some(Box::new(NSErrorError(err))),
            String::new(),
        )
    }

    pub(super) fn from_kind_and_nserror(kind: ErrorKind, err: Option<Retained<NSError>>) -> Self {
        match err {
            Some(err) => crate::Error::new(kind, Some(Box::new(NSErrorError(err))), String::new()),
            None => kind.into(),
        }
    }
}

fn kind_from_nserror(value: &NSError) -> ErrorKind {
    if value.domain().to_string() == "CBErrorDomain" {
        match CBError(value.code()) {
            CBError::OperationNotSupported => ErrorKind::NotSupported,
            CBError::NotConnected | CBError::PeripheralDisconnected => ErrorKind::NotConnected,
            CBError::ConnectionTimeout | CBError::EncryptionTimedOut => ErrorKind::Timeout,
            CBError::InvalidParameters | CBError::InvalidHandle | CBError::UUIDNotAllowed | CBError::UnknownDevice => {
                ErrorKind::InvalidParameter
            }
            CBError::ConnectionFailed
            | CBError::PeerRemovedPairingInformation
            | CBError::ConnectionLimitReached
            | CBError::TooManyLEPairedDevices => ErrorKind::ConnectionFailed,
            CBError::Unknown | CBError::OutOfSpace | CBError::OperationCancelled | CBError::AlreadyAdvertising => {
                ErrorKind::Other
            }
            _ => ErrorKind::Other,
        }
    } else if value.domain().to_string() == "CBATTErrorDomain" {
        let n = value.code();
        if let Ok(n) = u8::try_from(n) {
            ErrorKind::Protocol(AttError::from(n))
        } else {
            ErrorKind::Other
        }
    } else {
        ErrorKind::Other
    }
}

struct NSErrorError(Retained<NSError>);

impl std::fmt::Debug for NSErrorError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(&self.0, f)
    }
}

impl std::fmt::Display for NSErrorError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        std::fmt::Display::fmt(&self.localizedDescription(), f)
    }
}

impl std::error::Error for NSErrorError {}

impl std::ops::Deref for NSErrorError {
    type Target = NSError;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}