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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#![cfg_attr(not(feature = "std"), no_std)]
#![warn(
future_incompatible,
missing_abi,
nonstandard_style,
rust_2018_idioms,
trivial_casts,
trivial_numeric_casts,
unused,
unused_crate_dependencies,
unused_import_braces,
unused_lifetimes,
unused_qualifications,
rustdoc::all,
clippy::cargo,
clippy::pedantic,
)]
pub mod component;
pub mod computer;
pub mod descriptor;
pub mod error;
pub mod execute;
use core::fmt::{Display, Formatter};
use core::str::FromStr;
use minicbor::{
data::{Tag, Type},
decode, encode,
};
use uuid::Uuid;
#[derive(Clone, Copy, Debug, Default, Hash, Eq, Ord, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct Address(Uuid);
impl Address {
#[must_use = "This function is only useful for its return value"]
pub const fn as_bytes(&self) -> &[u8; 16] {
self.0.as_bytes()
}
#[must_use = "This function is only useful for its return value"]
pub const fn from_bytes(b: [u8; 16]) -> Self {
Self(Uuid::from_bytes(b))
}
}
impl Display for Address {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> {
self.0.fmt(f)
}
}
impl FromStr for Address {
type Err = <Uuid as FromStr>::Err;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Self(<Uuid as FromStr>::from_str(s)?))
}
}
impl decode::Decode<'_> for Address {
fn decode(d: &mut decode::Decoder<'_>) -> Result<Self, decode::Error> {
use core::convert::TryInto;
let mut datatype = d.datatype()?;
if datatype == Type::Tag {
let tag = d.tag()?;
if tag != Tag::Unassigned(39) {
return Err(decode::Error::Message("expected tag 39"));
}
datatype = d.datatype()?;
}
match datatype {
Type::Bytes => {
let b = d.bytes()?;
Ok(Self::from_bytes(b.try_into().map_err(|_| {
decode::Error::Message("expected 16 bytes")
})?))
}
Type::String => {
let s = d.str()?;
Ok(
Self::from_str(s)
.map_err(|_| decode::Error::Message("expected UUID string"))?,
)
}
_ => Err(decode::Error::Message("expected byte or UTF-8 string")),
}
}
}
impl encode::Encode for Address {
fn encode<W: encode::Write>(
&self,
e: &mut encode::Encoder<W>,
) -> Result<(), encode::Error<W::Error>> {
e.tag(Tag::Unassigned(39))?.bytes(self.as_bytes())?;
Ok(())
}
}
#[cfg(feature = "panic")]
#[macro_export]
macro_rules! panic_or_trap {
($message: literal) => {
core::panic!($message)
};
}
#[cfg(not(feature = "panic"))]
#[macro_export]
macro_rules! panic_or_trap {
($message: literal) => {
unsafe { core::arch::wasm32::unreachable() }
};
}
mod helpers;