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
96
97
98
99
100
101
102
103
104
105
106
#![no_std]
extern crate alloc;
mod blockchain;
mod private;
mod random;
mod special;
mod unique;
pub use blockchain::BlockchainId;
use core::fmt;
pub use private::PrivateId;
pub use random::RandomId;
pub use special::SpecialId;
pub use unique::UniqueId;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
pub const ID_PARENT: Id = SpecialId::new([0x00, 0x00]).id();
pub const ID_ALL: Id = SpecialId::new([0xFF, 0xFF]).id();
pub(crate) const ID_LEN: usize = 33;
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum IdKind {
Private = 0x00,
Random = 0x40,
Special = 0x60,
Unique = 0x80,
Blockchain = 0xA0,
Unknow,
}
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub struct Id {
len: usize,
buf: [u8; ID_LEN],
}
impl Id {
pub const INVALID: Id = Id {
len: 0,
buf: [0; ID_LEN],
};
pub const fn new(id: &[u8]) -> Id {
let mut buf: [u8; ID_LEN] = [0; ID_LEN];
let len = id.len();
let mut i = 0;
while i < len {
buf[i] = id[i];
i += 1;
}
Id { len, buf }
}
pub fn split_buf(buf: &[u8]) -> (Id, &[u8]) {
let (id, rest) = buf.split_at(((buf[0] & 0x1F) + 2) as usize);
let id = id.into();
return (id, rest);
}
}
#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl Id {
pub fn kind(&self) -> IdKind {
if self.len as u8 != ((self.buf[0] & 0x1F) + 2) {
return IdKind::Unknow;
}
match self.buf[0] & 0xE0 {
x if x == IdKind::Unique as u8 => IdKind::Unique,
x if x == IdKind::Private as u8 => IdKind::Private,
x if x == IdKind::Random as u8 => IdKind::Random,
x if x == IdKind::Blockchain as u8 => IdKind::Blockchain,
x if x == IdKind::Special as u8 => IdKind::Special,
_ => IdKind::Unknow,
}
}
}
impl fmt::Debug for Id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Id{:?}({:02X?})", self.kind(), &self.buf[..self.len])
}
}
impl From<&[u8]> for Id {
fn from(id: &[u8]) -> Self {
Id::new(id)
}
}
impl core::ops::Deref for Id {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.buf[..self.len]
}
}
impl AsRef<[u8]> for Id {
fn as_ref(&self) -> &[u8] {
&self.buf[..self.len]
}
}