1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
use {
    crate::{bytes::*, uuid::*, Error},
    core::{cmp::PartialEq, fmt},
};

/// ATT protocol UUID (either a 16 or a 128-bit UUID).
///
/// 32-bit UUIDs are not supported by ATT are must be converted to 128-bit UUIDs.
#[derive(Copy, Clone, Eq)]
pub enum AttUuid {
    Uuid16(Uuid16),
    Uuid128(Uuid),
}

impl FromBytes<'_> for AttUuid {
    fn from_bytes(bytes: &mut ByteReader) -> Result<Self, Error> {
        Ok(match bytes.bytes_left() {
            2 => AttUuid::Uuid16(Uuid16::from_bytes(bytes)?),
            16 => AttUuid::Uuid128(<Uuid as FromBytes>::from_bytes(bytes)?),
            _ => return Err(Error::InvalidLength),
        })
    }
}

impl ToBytes for AttUuid {
    fn to_bytes(&self, writer: &mut ByteWriter) -> Result<(), Error> {
        match self {
            AttUuid::Uuid16(uuid) => uuid.to_bytes(writer),
            AttUuid::Uuid128(uuid) => uuid.to_bytes(writer),
        }
    }
}

impl PartialEq for AttUuid {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            // 16-bit UUIDs can be compared directly
            (AttUuid::Uuid16(a), AttUuid::Uuid16(b)) => a == b,

            // All other combinations need to convert to 128-bit UUIDs
            (AttUuid::Uuid128(a), b) | (b, AttUuid::Uuid128(a)) => {
                let b: Uuid = (*b).into();
                *a == b
            }
        }
    }
}

impl PartialEq<Uuid16> for AttUuid {
    fn eq(&self, other: &Uuid16) -> bool {
        self == &Self::from(*other)
    }
}

impl PartialEq<Uuid> for AttUuid {
    fn eq(&self, other: &Uuid) -> bool {
        self == &Self::from(*other)
    }
}

impl From<Uuid16> for AttUuid {
    fn from(uu: Uuid16) -> Self {
        AttUuid::Uuid16(uu)
    }
}

impl From<Uuid32> for AttUuid {
    fn from(uu: Uuid32) -> Self {
        AttUuid::Uuid128(uu.into())
    }
}

impl From<Uuid> for AttUuid {
    fn from(uu: Uuid) -> Self {
        AttUuid::Uuid128(uu)
    }
}

impl Into<Uuid> for AttUuid {
    fn into(self) -> Uuid {
        match self {
            AttUuid::Uuid16(u) => u.into(),
            AttUuid::Uuid128(u) => u,
        }
    }
}

impl fmt::Debug for AttUuid {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            AttUuid::Uuid16(u) => u.fmt(f),
            AttUuid::Uuid128(u) => u.fmt(f),
        }
    }
}