1#![cfg_attr(not(feature = "std"), no_std)]
12#![allow(unused_doc_comments)]
13extern crate alloc;
35
36extern crate core;
37#[cfg(feature = "std")]
38extern crate std;
39#[cfg(feature = "std")]
40use std::io::Error;
41
42use crate::config::{
43 DataEndpoint, DataType, get_endpoint_meta, get_message_meta, max_data_type_id, max_endpoint_id,
44 runtime_static_hex_length, runtime_static_string_length,
45};
46use crate::macros::{ReprI32Enum, ReprU32Enum};
47use alloc::sync::Arc;
48use core::fmt::Formatter;
49use core::mem::size_of;
50use core::ops::Mul;
51
52#[cfg(all(test, feature = "std"))]
57mod tests;
58
59#[cfg(feature = "python")]
60#[cfg(feature = "std")]
61mod python_api;
62
63#[cfg(all(not(feature = "std"), target_os = "none"))]
71unsafe extern "C" {
72 fn seds_error_msg(msg: *const u8, len: usize);
73}
74
75#[cfg(all(not(feature = "std"), target_os = "none"))]
76mod embedded_alloc {
77 use core::alloc::{GlobalAlloc, Layout};
78 use core::mem::size_of;
79
80 unsafe extern "C" {
81 fn telemetryMalloc(size: usize) -> *mut core::ffi::c_void;
82 fn telemetryFree(ptr: *mut core::ffi::c_void);
83 fn telemetry_panic_hook(msg: *const u8, len: usize);
84 }
85
86 struct TelemetryAlloc;
89
90 #[inline]
91 fn align_up(addr: usize, align: usize) -> usize {
92 (addr + (align - 1)) & !(align - 1)
93 }
94
95 unsafe impl GlobalAlloc for TelemetryAlloc {
96 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
97 let align = layout.align().max(size_of::<usize>());
98 let header = size_of::<usize>();
99 let total = match layout
100 .size()
101 .checked_add(align)
102 .and_then(|v| v.checked_add(header))
103 {
104 Some(v) => v,
105 None => return core::ptr::null_mut(),
106 };
107
108 let raw = unsafe { telemetryMalloc(total) as *mut u8 };
109 if raw.is_null() {
110 return core::ptr::null_mut();
111 }
112
113 let base = raw as usize + header;
114 let aligned = align_up(base, align) as *mut u8;
115
116 unsafe {
118 let slot = (aligned as *mut usize).offset(-1);
119 *slot = raw as usize;
120 }
121
122 aligned
123 }
124
125 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
126 if ptr.is_null() {
127 return;
128 }
129
130 let raw = unsafe {
131 let slot = (ptr as *mut usize).offset(-1);
132 *slot as *mut core::ffi::c_void
133 };
134 unsafe { telemetryFree(raw) };
135 }
136 }
137
138 #[global_allocator]
139 static A: TelemetryAlloc = TelemetryAlloc;
140
141 use core::panic::PanicInfo;
143
144 #[panic_handler]
145 fn panic(_info: &PanicInfo) -> ! {
146 let msg = b"rust panic";
147 unsafe {
148 telemetry_panic_hook(msg.as_ptr(), msg.len());
149 }
150
151 loop {}
153 }
154
155 }
158
159mod binding_options;
167mod c_api;
168pub mod config;
169#[cfg(feature = "cryptography")]
170pub mod crypto;
171pub mod diagnostics;
172#[cfg(feature = "discovery")]
173pub mod discovery;
174mod lock;
175mod macros;
176pub mod memory_admission;
177pub mod packet;
178mod shared_bytes;
179pub use shared_bytes::SharedBytes;
180#[cfg(feature = "compact-packet-store")]
181pub mod packet_store;
182mod queue;
183pub mod relay;
184pub mod router;
185mod side_transport;
186mod small_payload;
187mod small_sort;
188#[cfg(feature = "timesync")]
189pub mod timesync;
190mod varint;
191pub mod wire_format;
192pub const MAX_VALUE_DATA_ENDPOINT: u32 = 255;
198
199pub const MAX_VALUE_DATA_TYPE: u32 = 4095;
201
202pub const MAX_VALUE_ROUTE_SELECTION_MODE: i32 = 2;
204
205impl ReprU32Enum for DataType {
206 const MAX: u32 = u32::MAX;
207
208 #[inline]
209 fn from_u32(x: u32) -> Option<Self> {
210 DataType::try_from_u32(x)
211 }
212}
213
214impl ReprU32Enum for DataEndpoint {
215 const MAX: u32 = u32::MAX;
216
217 #[inline]
218 fn from_u32(x: u32) -> Option<Self> {
219 DataEndpoint::try_from_u32(x)
220 }
221}
222
223#[inline]
224pub fn current_max_endpoint_id() -> u32 {
225 max_endpoint_id()
226}
227
228#[inline]
229pub fn current_max_data_type_id() -> u32 {
230 max_data_type_id()
231}
232
233#[repr(i32)]
234#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
235pub enum RouteSelectionMode {
236 Fanout = 0,
237 Weighted = 1,
238 Failover = 2,
239}
240
241impl_repr_i32_enum!(
242 RouteSelectionMode,
243 RouteSelectionMode::Fanout as i32,
244 RouteSelectionMode::Failover as i32
245);
246
247#[inline]
248const fn parse_usize(s: &str) -> usize {
249 let bytes = s.as_bytes();
250 let mut i = 0;
251 let mut val = 0;
252
253 while i < bytes.len() {
254 let c = bytes[i];
255 if c < b'0' || c > b'9' {
256 panic!("Invalid digit");
257 }
258 val = val * 10 + (c - b'0') as usize;
259 i += 1;
260 }
261 val
262}
263
264#[inline]
265pub const fn parse_f64(s: &str) -> f64 {
266 let bytes = s.as_bytes();
267 let mut i = 0;
268
269 if bytes.is_empty() {
270 panic!("empty string");
271 }
272
273 let mut sign = 1.0;
275 if bytes[i] == b'-' {
276 sign = -1.0;
277 i += 1;
278 } else if bytes[i] == b'+' {
279 i += 1;
280 }
281
282 let mut int_part: f64 = 0.0;
283 let mut has_digits = false;
284
285 while i < bytes.len() && bytes[i] >= b'0' && bytes[i] <= b'9' {
286 int_part = int_part * 10.0 + (bytes[i] - b'0') as f64;
287 i += 1;
288 has_digits = true;
289 }
290
291 let mut frac_part: f64 = 0.0;
292 let mut scale: f64 = 1.0;
293
294 if i < bytes.len() && bytes[i] == b'.' {
295 i += 1;
296
297 while i < bytes.len() && bytes[i] >= b'0' && bytes[i] <= b'9' {
298 scale *= 10.0;
299 frac_part += (bytes[i] - b'0') as f64 / scale;
300 i += 1;
301 has_digits = true;
302 }
303 }
304
305 if !has_digits || i != bytes.len() {
306 panic!("invalid f64 literal");
307 }
308
309 sign * (int_part + frac_part)
310}
311
312#[inline(always)]
313const fn parse_strings(s: &str) -> &str {
314 s
315}
316
317#[inline]
318pub const fn parse_u8(s: &str) -> u8 {
319 let bytes = s.as_bytes();
320 let mut i = 0;
321 let mut val: u16 = 0;
322
323 if bytes.is_empty() {
324 panic!("empty string");
325 }
326
327 while i < bytes.len() {
328 let c = bytes[i];
329 if c < b'0' || c > b'9' {
330 panic!("invalid digit in u8");
331 }
332
333 val = val * 10 + (c - b'0') as u16;
334 if val > 255 {
335 panic!("u8 overflow");
336 }
337
338 i += 1;
339 }
340
341 val as u8
342}
343
344#[inline]
345pub const fn parse_u128(s: &str) -> u128 {
346 let bytes = s.as_bytes();
347 let mut i = 0;
348 let mut val: u128 = 0;
349
350 if bytes.is_empty() {
351 panic!("empty string");
352 }
353
354 while i < bytes.len() {
355 let c = bytes[i];
356 if c < b'0' || c > b'9' {
357 panic!("invalid digit in u128");
358 }
359
360 let digit = (c - b'0') as u128;
361
362 if val > (u128::MAX - digit) / 10 {
365 panic!("u128 overflow");
366 }
367
368 val = val * 10 + digit;
369 i += 1;
370 }
371
372 val
373}
374
375#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
379pub struct EndpointMeta {
380 #[cfg(feature = "std")]
382 name: Arc<str>,
383 #[cfg(not(feature = "std"))]
384 name: &'static str,
385 #[cfg(feature = "std")]
387 description: Arc<str>,
388 #[cfg(not(feature = "std"))]
389 description: &'static str,
390 link_local_only: bool,
392}
393
394impl EndpointMeta {
395 #[cfg(feature = "std")]
396 pub(crate) fn name_ref(&self) -> &str {
397 self.name.as_ref()
398 }
399
400 #[cfg(not(feature = "std"))]
401 pub(crate) fn name_ref(&self) -> &str {
402 self.name
403 }
404
405 #[cfg(feature = "std")]
406 pub(crate) fn description_ref(&self) -> &str {
407 self.description.as_ref()
408 }
409
410 #[cfg(not(feature = "std"))]
411 pub(crate) fn description_ref(&self) -> &str {
412 self.description
413 }
414
415 #[cfg(feature = "std")]
421 pub fn as_str(&self) -> Arc<str> {
422 self.name.clone()
423 }
424
425 #[cfg(not(feature = "std"))]
426 pub fn as_str(&self) -> &'static str {
427 self.name
428 }
429
430 #[inline]
432 #[cfg(feature = "std")]
433 pub fn description(&self) -> Arc<str> {
434 self.description.clone()
435 }
436
437 #[cfg(not(feature = "std"))]
438 pub fn description(&self) -> &'static str {
439 self.description
440 }
441
442 #[inline]
444 pub fn is_link_local_only(&self) -> bool {
445 self.link_local_only
446 }
447}
448
449impl DataEndpoint {
450 #[cfg(feature = "std")]
456 pub fn as_str(&self) -> Arc<str> {
457 get_endpoint_meta(*self).name
458 }
459
460 #[cfg(not(feature = "std"))]
461 pub fn as_str(&self) -> &'static str {
462 get_endpoint_meta(*self).name
463 }
464
465 #[cfg(feature = "std")]
467 pub fn description(&self) -> Arc<str> {
468 get_endpoint_meta(*self).description
469 }
470
471 #[cfg(not(feature = "std"))]
472 pub fn description(&self) -> &'static str {
473 get_endpoint_meta(*self).description
474 }
475
476 #[inline]
478 pub fn is_link_local_only(&self) -> bool {
479 get_endpoint_meta(*self).link_local_only
480 }
481}
482
483#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
485pub enum MessageElement {
486 Static(usize, MessageDataType, MessageClass),
490 Dynamic(MessageDataType, MessageClass),
494}
495
496impl MessageElement {
497 #[inline]
499 pub const fn data_type(&self) -> MessageDataType {
500 match self {
501 MessageElement::Static(_, dt, _) => *dt,
502 MessageElement::Dynamic(dt, _) => *dt,
503 }
504 }
505
506 #[inline]
508 pub const fn message_type(&self) -> MessageClass {
509 match self {
510 MessageElement::Static(_, _, mt) => *mt,
511 MessageElement::Dynamic(_, mt) => *mt,
512 }
513 }
514}
515
516#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
518#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
519pub enum ReliableMode {
520 #[cfg_attr(feature = "serde", serde(rename = "Off"))]
522 None,
523 Ordered,
525 Unordered,
527}
528
529#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
531pub enum E2eEncryptionPolicy {
532 PreferOff,
534 PreferOn,
536 RequireOn,
538}
539
540#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
542pub struct MessageMeta {
543 #[cfg(feature = "std")]
544 name: Arc<str>,
545 #[cfg(not(feature = "std"))]
546 name: &'static str,
547 #[cfg(feature = "std")]
549 description: Arc<str>,
550 #[cfg(not(feature = "std"))]
551 description: &'static str,
552 element: MessageElement,
554 #[cfg(feature = "std")]
556 endpoints: Arc<[DataEndpoint]>,
557 #[cfg(not(feature = "std"))]
558 endpoints: &'static [DataEndpoint],
559 reliable: ReliableMode,
561 priority: u8,
563 e2e_encryption: E2eEncryptionPolicy,
565}
566
567impl MessageMeta {
568 #[cfg(feature = "std")]
569 pub(crate) fn name_ref(&self) -> &str {
570 self.name.as_ref()
571 }
572
573 #[cfg(not(feature = "std"))]
574 pub(crate) fn name_ref(&self) -> &str {
575 self.name
576 }
577
578 #[cfg(feature = "std")]
579 pub(crate) fn description_ref(&self) -> &str {
580 self.description.as_ref()
581 }
582
583 #[cfg(not(feature = "std"))]
584 pub(crate) fn description_ref(&self) -> &str {
585 self.description
586 }
587
588 #[cfg(feature = "std")]
589 pub(crate) fn endpoints_ref(&self) -> &[DataEndpoint] {
590 self.endpoints.as_ref()
591 }
592
593 #[cfg(not(feature = "std"))]
594 pub(crate) fn endpoints_ref(&self) -> &[DataEndpoint] {
595 self.endpoints
596 }
597}
598
599impl DataType {
600 #[cfg(feature = "std")]
602 pub fn as_str(&self) -> Arc<str> {
603 get_message_meta(*self).name
604 }
605
606 #[cfg(not(feature = "std"))]
607 pub fn as_str(&self) -> &'static str {
608 get_message_meta(*self).name
609 }
610
611 #[cfg(feature = "std")]
613 pub fn description(&self) -> Arc<str> {
614 get_message_meta(*self).description
615 }
616
617 #[cfg(not(feature = "std"))]
618 pub fn description(&self) -> &'static str {
619 get_message_meta(*self).description
620 }
621}
622#[inline]
628pub fn message_meta(ty: DataType) -> MessageMeta {
629 get_message_meta(ty)
630}
631
632#[inline]
634pub fn is_reliable_type(ty: DataType) -> bool {
635 !matches!(get_message_meta(ty).reliable, ReliableMode::None)
636}
637
638#[inline]
640pub fn reliable_mode(ty: DataType) -> ReliableMode {
641 get_message_meta(ty).reliable
642}
643
644#[inline]
646pub fn message_priority(ty: DataType) -> u8 {
647 get_message_meta(ty).priority
648}
649
650#[inline]
658pub fn transport_priority(ty: DataType) -> u8 {
659 match ty {
660 DataType::ReliableAck | DataType::ReliablePartialAck | DataType::ReliablePacketRequest => {
663 255
664 }
665
666 DataType::DiscoveryAnnounce
668 | DataType::DiscoveryTimeSyncSources
669 | DataType::DiscoveryTopology
670 | DataType::DiscoveryTopologyRequest
671 | DataType::DiscoveryLeave
672 | DataType::DiscoveryLinkCapabilities
673 | DataType::DiscoveryAddress => 255,
674
675 DataType::DiscoverySchema
680 | DataType::DiscoverySchemaRequest
681 | DataType::ManagedVariableRequest
682 | DataType::ManagedVariableValue
683 | DataType::TimeSyncAnnounce
684 | DataType::TimeSyncRequest
685 | DataType::TimeSyncResponse => 254,
686
687 _ => message_priority(ty).min(253),
689 }
690}
691
692#[inline]
695pub(crate) fn scheduler_priority(ty: DataType) -> u8 {
696 transport_priority(ty)
697}
698
699#[inline]
701pub fn message_e2e_encryption_policy(ty: DataType) -> E2eEncryptionPolicy {
702 get_message_meta(ty).e2e_encryption
703}
704
705impl Mul<MessageElement> for usize {
708 type Output = usize;
709
710 #[inline]
711 fn mul(self, rhs: MessageElement) -> usize {
712 self * rhs.into()
713 }
714}
715
716impl Mul<usize> for MessageElement {
717 type Output = usize;
718
719 #[inline]
720 fn mul(self, rhs: usize) -> usize {
721 self.into() * rhs
722 }
723}
724
725impl MessageElement {
726 #[inline]
731 fn into(self) -> usize {
732 match self {
733 MessageElement::Static(a, _, _) => a,
734 _ => 0,
735 }
736 }
737}
738
739#[inline]
749pub fn get_needed_message_size(ty: DataType) -> usize {
750 data_type_size(get_data_type(ty)) * get_message_meta(ty).element
751}
752
753#[inline]
759pub fn get_info_type(ty: DataType) -> MessageClass {
760 get_message_meta(ty).element.message_type()
761}
762
763#[inline]
770pub fn get_data_type(ty: DataType) -> MessageDataType {
771 get_message_meta(ty).element.data_type()
772}
773
774#[inline]
780#[cfg(feature = "std")]
781pub fn get_message_name(ty: DataType) -> Arc<str> {
782 get_message_meta(ty).name
783}
784
785#[cfg(not(feature = "std"))]
786pub fn get_message_name(ty: DataType) -> &'static str {
787 get_message_meta(ty).name
788}
789
790#[inline]
796#[cfg(feature = "std")]
797pub fn endpoints_from_datatype(ty: DataType) -> Arc<[DataEndpoint]> {
798 get_message_meta(ty).endpoints
799}
800
801#[cfg(not(feature = "std"))]
802pub fn endpoints_from_datatype(ty: DataType) -> &'static [DataEndpoint] {
803 get_message_meta(ty).endpoints
804}
805
806#[allow(dead_code)]
811#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
812pub enum MessageDataType {
813 Float64,
814 Float32,
815 UInt8,
816 UInt16,
817 UInt32,
818 UInt64,
819 UInt128,
820 Int8,
821 Int16,
822 Int32,
823 Int64,
824 Int128,
825 Bool,
826 String,
827 Binary,
828 NoData,
829}
830
831#[inline]
840pub fn data_type_size(dt: MessageDataType) -> usize {
841 match dt {
842 MessageDataType::Float64 => size_of::<f64>(),
843 MessageDataType::Float32 => size_of::<f32>(),
844 MessageDataType::UInt8 => size_of::<u8>(),
845 MessageDataType::UInt16 => size_of::<u16>(),
846 MessageDataType::UInt32 => size_of::<u32>(),
847 MessageDataType::UInt64 => size_of::<u64>(),
848 MessageDataType::UInt128 => size_of::<u128>(),
849 MessageDataType::Int8 => size_of::<i8>(),
850 MessageDataType::Int16 => size_of::<i16>(),
851 MessageDataType::Int32 => size_of::<i32>(),
852 MessageDataType::Int64 => size_of::<i64>(),
853 MessageDataType::Int128 => size_of::<i128>(),
854 MessageDataType::Bool => size_of::<bool>(),
855 MessageDataType::String => runtime_static_string_length(),
856 MessageDataType::Binary => runtime_static_hex_length(),
857 MessageDataType::NoData => 0,
858 }
859}
860
861#[allow(dead_code)]
863#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
864pub enum MessageClass {
865 Data,
867 Error,
869 Warning,
871}
872
873#[derive(Debug, Clone, PartialEq, Eq)]
882pub enum TelemetryError {
883 GenericError(Option<Arc<str>>),
885
886 InvalidType,
888
889 SizeMismatch { expected: usize, got: usize },
891
892 SizeMismatchError,
894
895 EmptyEndpoints,
897
898 TimestampInvalid,
900
901 MissingPayload,
903
904 HandlerError(&'static str),
906
907 BadArg,
909
910 PermissionDenied,
912
913 Pack(&'static str),
915
916 Unpack(&'static str),
918
919 Io(&'static str),
921
922 InvalidUtf8,
924
925 TypeMismatch { expected: usize, got: usize },
927
928 InvalidLinkId(&'static str),
930
931 PacketTooLarge(&'static str),
933}
934
935impl TelemetryError {
936 pub const fn to_error_code(&self) -> TelemetryErrorCode {
939 match self {
940 TelemetryError::GenericError(_) => TelemetryErrorCode::GenericError,
941 TelemetryError::InvalidType => TelemetryErrorCode::InvalidType,
942 TelemetryError::SizeMismatch { .. } => TelemetryErrorCode::SizeMismatch,
943 TelemetryError::SizeMismatchError => TelemetryErrorCode::SizeMismatchError,
944 TelemetryError::EmptyEndpoints => TelemetryErrorCode::EmptyEndpoints,
945 TelemetryError::TimestampInvalid => TelemetryErrorCode::TimestampInvalid,
946 TelemetryError::MissingPayload => TelemetryErrorCode::MissingPayload,
947 TelemetryError::HandlerError(_) => TelemetryErrorCode::HandlerError,
948 TelemetryError::BadArg => TelemetryErrorCode::BadArg,
949 TelemetryError::PermissionDenied => TelemetryErrorCode::PermissionDenied,
950 TelemetryError::Pack(_) => TelemetryErrorCode::Pack,
951 TelemetryError::Unpack(_) => TelemetryErrorCode::Unpack,
952 TelemetryError::Io(_) => TelemetryErrorCode::Io,
953 TelemetryError::InvalidUtf8 => TelemetryErrorCode::InvalidUtf8,
954 TelemetryError::TypeMismatch { .. } => TelemetryErrorCode::TypeMismatch,
955 TelemetryError::InvalidLinkId(_) => TelemetryErrorCode::InvalidLinkId,
956 TelemetryError::PacketTooLarge(_) => TelemetryErrorCode::PacketTooLarge,
957 }
958 }
959}
960
961impl core::fmt::Display for TelemetryError {
963 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
964 core::fmt::Debug::fmt(self, f)
969 }
970}
971
972#[cfg(feature = "std")]
974impl std::error::Error for TelemetryError {
975 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
976 None
977 }
978}
979
980#[cfg(feature = "std")]
982impl From<Error> for TelemetryError {
983 fn from(error: Error) -> Self {
984 let str = error.to_string();
985 let astr: Arc<str> = Arc::from(str.as_str());
986 TelemetryError::GenericError(Some(astr))
987 }
988}
989
990#[cfg(feature = "std")]
992impl From<Box<dyn std::error::Error>> for TelemetryError {
993 fn from(err: Box<dyn std::error::Error>) -> Self {
994 let str = err.to_string();
995 let astr: Arc<str> = Arc::from(str.as_str());
996 TelemetryError::GenericError(Some(astr))
997 }
998}
999
1000#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1005#[repr(i32)]
1006pub enum TelemetryErrorCode {
1007 GenericError = -2,
1008 InvalidType = -3,
1009 SizeMismatch = -4,
1010 SizeMismatchError = -5,
1011 EmptyEndpoints = -6,
1012 TimestampInvalid = -7,
1013 MissingPayload = -8,
1014 HandlerError = -9,
1015 BadArg = -10,
1016 PermissionDenied = -11,
1017 Pack = -12,
1018 Unpack = -13,
1019 Io = -14,
1020 InvalidUtf8 = -15,
1021 TypeMismatch = -16,
1022 InvalidLinkId = -17,
1023 PacketTooLarge = -18,
1024}
1025
1026impl_repr_i32_enum!(
1028 TelemetryErrorCode,
1029 TelemetryErrorCode::MAX,
1030 TelemetryErrorCode::MIN
1031);
1032
1033impl TelemetryErrorCode {
1034 pub const MAX: i32 = TelemetryErrorCode::InvalidType as i32;
1036
1037 pub const MIN: i32 = TelemetryErrorCode::PacketTooLarge as i32;
1039
1040 #[inline]
1044 pub fn as_str(&self) -> &'static str {
1045 match self {
1046 TelemetryErrorCode::GenericError => "GenericError",
1047 TelemetryErrorCode::InvalidType => "{Invalid Type}",
1048 TelemetryErrorCode::SizeMismatch => "{Size Mismatch}",
1049 TelemetryErrorCode::SizeMismatchError => "{Size Mismatch Error}",
1050 TelemetryErrorCode::EmptyEndpoints => "{Empty Endpoints}",
1051 TelemetryErrorCode::TimestampInvalid => "{Timestamp Invalid}",
1052 TelemetryErrorCode::MissingPayload => "{Missing Payload}",
1053 TelemetryErrorCode::HandlerError => "{Handler Error}",
1054 TelemetryErrorCode::BadArg => "{Bad Arg}",
1055 TelemetryErrorCode::PermissionDenied => "{Permission Denied}",
1056 TelemetryErrorCode::Pack => "{Pack Error}",
1057 TelemetryErrorCode::Unpack => "{Unpack Error}",
1058 TelemetryErrorCode::Io => "{IO Error}",
1059 TelemetryErrorCode::InvalidUtf8 => "{Invalid UTF-8}",
1060 TelemetryErrorCode::TypeMismatch => "{Type Mismatch}",
1061 TelemetryErrorCode::InvalidLinkId => "{Invalid Link ID}",
1062 TelemetryErrorCode::PacketTooLarge => "{Packet Too Large}",
1063 }
1064 }
1065
1066 #[inline]
1074 pub fn try_from_i32(x: i32) -> Option<Self> {
1075 try_enum_from_i32(x)
1076 }
1077}
1078
1079pub type TelemetryResult<T> = Result<T, TelemetryError>;
1081
1082#[inline]
1094pub fn try_enum_from_u32<E: ReprU32Enum>(x: u32) -> Option<E> {
1095 if x > E::MAX {
1096 return None;
1097 }
1098 E::from_u32(x)
1099}
1100
1101#[inline]
1109pub fn try_enum_from_i32<E: ReprI32Enum>(x: i32) -> Option<E> {
1110 if x < E::MIN || x > E::MAX {
1111 return None;
1112 }
1113
1114 let e = unsafe { (&x as *const i32 as *const E).read() };
1116 Some(e)
1117}