unmp_id/
lib.rs

1//! unmp-id
2
3#![no_std]
4extern crate alloc;
5
6mod blockchain;
7mod private;
8mod random;
9mod special;
10mod unique;
11
12pub use blockchain::BlockchainId;
13use core::fmt;
14pub use private::PrivateId;
15pub use random::RandomId;
16pub use special::SpecialId;
17pub use unique::UniqueId;
18#[cfg(feature = "wasm")]
19use wasm_bindgen::prelude::*;
20
21/// 上级父设备地址
22pub const ID_PARENT: Id = SpecialId::new([0x00, 0x00]).id();
23/// 下级子设备地址
24pub const ID_ALL: Id = SpecialId::new([0xFF, 0xFF]).id();
25/// 地址最大长度
26pub(crate) const ID_LEN: usize = 33;
27
28/// unmp设备地址类型
29#[cfg_attr(feature = "wasm", wasm_bindgen)]
30#[derive(PartialEq, Eq, Clone, Copy, Debug)]
31pub enum IdKind {
32    Private = 0x00,
33    Random = 0x40,
34    Special = 0x60,
35    Unique = 0x80,
36    Blockchain = 0xA0,
37    Unknow,
38}
39/// unmp设备地址
40#[cfg_attr(feature = "wasm", wasm_bindgen)]
41#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
42pub struct Id {
43    len: usize,
44    buf: [u8; ID_LEN],
45}
46impl Id {
47    /// 无效ID
48    pub const INVALID: Id = Id {
49        len: 0,
50        buf: [0; ID_LEN],
51    };
52    /// 生成ID
53    pub const fn new(id: &[u8]) -> Id {
54        let mut buf: [u8; ID_LEN] = [0; ID_LEN];
55        let len = id.len();
56        let mut i = 0;
57        while i < len {
58            buf[i] = id[i];
59            i += 1;
60        }
61        Id { len, buf }
62    }
63    /// 从buf头部分割出Id并返回剩余buf
64    pub fn split_buf(buf: &[u8]) -> (Id, &[u8]) {
65        let (id, rest) = buf.split_at(((buf[0] & 0x1F) + 2) as usize);
66        let id = id.into();
67        return (id, rest);
68    }
69}
70#[cfg_attr(feature = "wasm", wasm_bindgen)]
71impl Id {
72    pub fn kind(&self) -> IdKind {
73        if self.len as u8 != ((self.buf[0] & 0x1F) + 2) {
74            return IdKind::Unknow;
75        }
76        match self.buf[0] & 0xE0 {
77            x if x == IdKind::Unique as u8 => IdKind::Unique,
78            x if x == IdKind::Private as u8 => IdKind::Private,
79            x if x == IdKind::Random as u8 => IdKind::Random,
80            x if x == IdKind::Blockchain as u8 => IdKind::Blockchain,
81            x if x == IdKind::Special as u8 => IdKind::Special,
82            _ => IdKind::Unknow,
83        }
84    }
85}
86impl fmt::Debug for Id {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        write!(f, "Id{:?}({:02X?})", self.kind(), &self.buf[..self.len])
89    }
90}
91impl From<&[u8]> for Id {
92    fn from(id: &[u8]) -> Self {
93        Id::new(id)
94    }
95}
96impl core::ops::Deref for Id {
97    type Target = [u8];
98    fn deref(&self) -> &Self::Target {
99        &self.buf[..self.len]
100    }
101}
102impl AsRef<[u8]> for Id {
103    fn as_ref(&self) -> &[u8] {
104        &self.buf[..self.len]
105    }
106}