1#![no_std]
13
14use core::{hash::Hash, marker::PhantomData, str::FromStr};
15use heapless::{consts, ArrayLength, String};
16use serde::{
17 de::{Deserializer, Visitor},
18 ser::Serializer,
19 Deserialize, Serialize,
20};
21
22pub mod arbitrator;
23pub mod component;
24
25pub type MaxPathLen = consts::U127;
27
28pub type MaxNameLen = consts::U32;
30
31#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone)]
33pub enum PubSubPath<'a> {
34 #[serde(borrow)]
36 Long(Path<'a>),
37
38 Short(u16),
42}
43
44#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone, Copy)]
46pub struct Version {
47 pub major: u8,
49
50 pub minor: u8,
52
53 pub trivial: u8,
55
56 pub misc: u8,
60}
61
62pub type Path<'a> = ManagedString<'a, MaxPathLen>;
64
65pub type Name<'a> = ManagedString<'a, MaxNameLen>;
67
68#[derive(Debug, Eq, PartialEq, Clone)]
72pub enum ManagedString<'a, T>
73where
74 T: ArrayLength<u8>,
75{
76 Owned(String<T>),
77 Borrow(&'a str),
78}
79
80impl<'a, T> Serialize for ManagedString<'a, T>
81where
82 T: ArrayLength<u8>,
83{
84 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86 where
87 S: Serializer,
88 {
89 serializer.serialize_str(self.as_str())
90 }
91}
92
93impl<'a, 'de: 'a, T> Deserialize<'de> for ManagedString<'a, T>
94where
95 T: ArrayLength<u8> + Sized,
96{
97 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
99 where
100 D: Deserializer<'de>,
101 {
102 deserializer.deserialize_str(ManagedStringVisitor::new())
103 }
104}
105
106struct ManagedStringVisitor<'a, T>
107where
108 T: ArrayLength<u8> + Sized,
109{
110 _t: PhantomData<T>,
111 _lt: PhantomData<&'a ()>,
112}
113
114impl<'a, T> ManagedStringVisitor<'a, T>
115where
116 T: ArrayLength<u8> + Sized,
117{
118 fn new() -> ManagedStringVisitor<'a, T> {
119 Self {
120 _t: PhantomData,
121 _lt: PhantomData,
122 }
123 }
124}
125
126impl<'de: 'a, 'a, T> Visitor<'de> for ManagedStringVisitor<'a, T>
127where
128 T: ArrayLength<u8> + Sized,
129{
130 type Value = ManagedString<'a, T>;
131
132 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
133 write!(formatter, "a borrowable str")
134 }
135
136 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
137 where
138 E: serde::de::Error,
139 {
140 Ok(ManagedString::Borrow(value))
142 }
143}
144
145impl<'a, T> ManagedString<'a, T>
146where
147 T: ArrayLength<u8>,
148{
149 pub fn as_str(&self) -> &str {
151 match self {
152 ManagedString::Owned(o) => o.as_str(),
153 ManagedString::Borrow(s) => s,
154 }
155 }
156
157 pub fn as_borrowed(&'a self) -> ManagedString<'a, T> {
159 ManagedString::Borrow(self.as_str())
160 }
161
162 pub fn try_from_str(input: &str) -> Result<ManagedString<'static, T>, ()> {
167 Ok(ManagedString::Owned(String::from_str(input)?))
168 }
169
170 pub fn borrow_from_str(input: &str) -> ManagedString<T> {
172 ManagedString::Borrow(input)
173 }
174
175 pub fn try_to_owned(&self) -> Result<ManagedString<'static, T>, ()> {
180 ManagedString::try_from_str(self.as_str())
181 }
182}
183
184#[derive(Debug, Serialize, Deserialize, Eq, PartialEq, Clone, Copy, Hash)]
186pub struct Uuid([u8; 16]);
187
188impl Uuid {
189 pub fn from_bytes(by: [u8; 16]) -> Self {
191 Uuid(by)
192 }
193
194 pub fn as_bytes(&self) -> &[u8; 16] {
196 &self.0
197 }
198
199 pub fn as_slice(&self) -> &[u8] {
201 &self.0[..]
202 }
203}
204
205pub fn matches(subscr: &str, publ: &str) -> bool {
218 if subscr.is_empty() || publ.is_empty() {
219 return false;
220 }
221
222 let mut s_iter = subscr.split('/');
223 let mut p_iter = publ.split('/');
224
225 loop {
226 match (s_iter.next(), p_iter.next()) {
227 (Some("+"), Some(_)) => continue,
228 (Some("#"), _) | (None, None) => return true,
229 (Some(lhs), Some(rhs)) if lhs == rhs => continue,
230 _ => return false,
231 }
232 }
233}