1#![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
21pub const ID_PARENT: Id = SpecialId::new([0x00, 0x00]).id();
23pub const ID_ALL: Id = SpecialId::new([0xFF, 0xFF]).id();
25pub(crate) const ID_LEN: usize = 33;
27
28#[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#[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 pub const INVALID: Id = Id {
49 len: 0,
50 buf: [0; ID_LEN],
51 };
52 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 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}