1#![doc(
4 html_logo_url = "https://commonware.xyz/imgs/rustdoc_logo.svg",
5 html_favicon_url = "https://commonware.xyz/favicon.ico"
6)]
7#![cfg_attr(not(any(feature = "std", test)), no_std)]
8
9commonware_macros::stability_scope!(ALPHA, cfg(any(feature = "std", test)) {
10 pub use rng::{Entropy, FuzzRng, ScriptedRng, TestRng, test_rng};
11});
12commonware_macros::stability_scope!(BETA {
13 #[cfg(not(feature = "std"))]
14 extern crate alloc;
15
16 pub trait Widen<T> {
19 fn widen(self) -> T;
21 }
22
23 macro_rules! impl_widen {
24 ($($nz:ty => $($t:ty),+);+ $(;)?) => {$($(
25 impl Widen<$t> for $nz {
26 #[inline]
27 fn widen(self) -> $t {
28 <$t>::from(self.get())
29 }
30 }
31 )+)+};
32 }
33 impl_widen!(
34 core::num::NonZeroU8 => u16, u32, u64, u128, usize;
35 core::num::NonZeroU16 => u32, u64, u128, usize;
36 core::num::NonZeroU32 => u64, u128;
37 core::num::NonZeroU64 => u128;
38 );
39
40 impl Widen<usize> for u32 {
41 #[inline]
42 fn widen(self) -> usize {
43 const { assert!(Self::BITS <= usize::BITS) };
44 self as usize
45 }
46 }
47
48 impl Widen<u64> for usize {
49 #[inline]
50 fn widen(self) -> u64 {
51 const { assert!(Self::BITS <= u64::BITS) };
52 self as u64
53 }
54 }
55
56 #[cfg(not(feature = "std"))]
57 use alloc::{boxed::Box, vec::Vec};
58 use bytes::{BufMut, BytesMut};
59 use core::time::Duration;
60 pub mod faults;
61 pub use faults::{Faults, N3f1, N5f1};
62
63 pub mod sequence;
64 pub use sequence::{Array, Span};
65
66 pub mod hostname;
67 pub use hostname::Hostname;
68
69 pub mod bitmap;
70 pub mod cache;
71 pub mod handles;
72 pub mod iter;
73 pub mod ordered;
74 pub mod prefetch;
75 pub mod probability;
76 pub use probability::Probability;
77 pub mod range;
78 pub mod sampling;
79
80 use commonware_codec::{
81 Buf, EncodeSize, Error as CodecError, MaxEncodeSize, Read, ReadExt, Write, varint::UInt,
82 };
83
84 pub const MAX_ALLOCATION_BYTES: usize = isize::MAX as usize;
90
91 pub const GOLDEN_RATIO: u64 = 0x9e37_79b9_7f4a_7c15;
96
97 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
103 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
104 pub struct Participant(u32);
105
106 impl Participant {
107 pub const fn new(index: u32) -> Self {
109 Self(index)
110 }
111
112 pub fn from_usize(index: usize) -> Self {
118 Self(u32::try_from(index).expect("participant index exceeds u32::MAX"))
119 }
120
121 pub const fn get(self) -> u32 {
123 self.0
124 }
125 }
126
127 impl From<Participant> for usize {
128 fn from(p: Participant) -> Self {
129 p.0 as Self
130 }
131 }
132
133 impl core::fmt::Display for Participant {
134 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
135 write!(f, "{}", self.0)
136 }
137 }
138
139 impl Read for Participant {
140 type Cfg = ();
141
142 fn read_cfg(buf: &mut impl Buf, _cfg: &Self::Cfg) -> Result<Self, CodecError> {
143 let value: u32 = UInt::read(buf)?.into();
144 Ok(Self(value))
145 }
146 }
147
148 impl Write for Participant {
149 fn write(&self, buf: &mut impl bytes::BufMut) {
150 UInt(self.0).write(buf);
151 }
152 }
153
154 impl EncodeSize for Participant {
155 fn encode_size(&self) -> usize {
156 UInt(self.0).encode_size()
157 }
158 }
159
160 impl MaxEncodeSize for Participant {
161 const MAX_ENCODE_SIZE: usize = UInt::<u32>::MAX_ENCODE_SIZE;
162 }
163
164 pub trait TryFromIterator<T>: Sized {
166 type Error;
168
169 fn try_from_iter<I: IntoIterator<Item = T>>(iter: I) -> Result<Self, Self::Error>;
171 }
172
173 pub trait TryCollect: Iterator + Sized {
175 fn try_collect<C: TryFromIterator<Self::Item>>(self) -> Result<C, C::Error> {
177 C::try_from_iter(self)
178 }
179 }
180
181 impl<I: Iterator> TryCollect for I {}
182
183 pub type BoxedError = Box<dyn core::error::Error + Send + Sync>;
185
186 pub fn union(a: &[u8], b: &[u8]) -> Vec<u8> {
188 let mut union = Vec::with_capacity(a.len() + b.len());
189 union.extend_from_slice(a);
190 union.extend_from_slice(b);
191 union
192 }
193
194 pub fn union_unique(namespace: &[u8], msg: &[u8]) -> Vec<u8> {
198 use commonware_codec::EncodeSize;
199 let len_prefix = namespace.len();
200 let mut buf =
201 BytesMut::with_capacity(len_prefix.encode_size() + namespace.len() + msg.len());
202 len_prefix.write(&mut buf);
203 BufMut::put_slice(&mut buf, namespace);
204 BufMut::put_slice(&mut buf, msg);
205 buf.into()
206 }
207
208 pub fn modulo(bytes: &[u8], n: u64) -> u64 {
216 assert_ne!(n, 0, "modulus must be non-zero");
217
218 let n = n as u128;
219 let mut result = 0u128;
220 for &byte in bytes {
221 result = (result << 8) | (byte as u128);
222 result %= n;
223 }
224
225 result as u64
227 }
228
229 pub const fn max(a: usize, b: usize) -> usize {
232 if a > b { a } else { b }
233 }
234
235 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
237 pub struct NonZeroDuration(Duration);
238
239 impl NonZeroDuration {
240 pub fn new(duration: Duration) -> Option<Self> {
242 if duration == Duration::ZERO {
243 None
244 } else {
245 Some(Self(duration))
246 }
247 }
248
249 pub fn new_panic(duration: Duration) -> Self {
251 Self::new(duration).expect("duration must be non-zero")
252 }
253
254 pub const fn get(self) -> Duration {
256 self.0
257 }
258 }
259
260 impl From<NonZeroDuration> for Duration {
261 fn from(nz_duration: NonZeroDuration) -> Self {
262 nz_duration.0
263 }
264 }
265});
266commonware_macros::stability_scope!(BETA, cfg(any(feature = "std", test)) {
267 pub mod rng;
268 pub use rng::sys_rng;
269});
270commonware_macros::stability_scope!(BETA, cfg(feature = "std") {
271 pub mod acknowledgement;
272 pub use acknowledgement::Acknowledgement;
273
274 pub mod net;
275 pub use net::IpAddrExt;
276
277 pub mod time;
278 pub use time::{DurationExt, SystemTimeExt};
279
280 pub mod rational;
281 pub use rational::BigRationalExt;
282
283 mod priority_set;
284 pub use priority_set::PrioritySet;
285
286 pub mod channel;
287 pub mod concurrency;
288 pub mod futures;
289 pub mod sync;
290
291 pub mod thread_local;
292 pub use thread_local::Cached;
293});
294#[cfg(not(any(
295 commonware_stability_GAMMA,
296 commonware_stability_DELTA,
297 commonware_stability_EPSILON,
298 commonware_stability_RESERVED
299)))] pub mod vec;
301
302#[macro_export]
306macro_rules! NZUsize {
307 ($val:literal) => {
308 const { ::core::num::NonZeroUsize::new($val).expect("value must be non-zero") }
309 };
310 ($val:expr) => {
311 ::core::num::NonZeroUsize::new($val).expect("value must be non-zero")
313 };
314}
315
316#[macro_export]
320macro_rules! NZU8 {
321 ($val:literal) => {
322 const { ::core::num::NonZeroU8::new($val).expect("value must be non-zero") }
323 };
324 ($val:expr) => {
325 ::core::num::NonZeroU8::new($val).expect("value must be non-zero")
327 };
328}
329
330#[macro_export]
334macro_rules! NZU16 {
335 ($val:literal) => {
336 const { ::core::num::NonZeroU16::new($val).expect("value must be non-zero") }
337 };
338 ($val:expr) => {
339 ::core::num::NonZeroU16::new($val).expect("value must be non-zero")
341 };
342}
343
344#[macro_export]
348macro_rules! NZU32 {
349 ($val:literal) => {
350 const { ::core::num::NonZeroU32::new($val).expect("value must be non-zero") }
351 };
352 ($val:expr) => {
353 ::core::num::NonZeroU32::new($val).expect("value must be non-zero")
355 };
356}
357
358#[macro_export]
362macro_rules! NZU64 {
363 ($val:literal) => {
364 const { ::core::num::NonZeroU64::new($val).expect("value must be non-zero") }
365 };
366 ($val:expr) => {
367 ::core::num::NonZeroU64::new($val).expect("value must be non-zero")
369 };
370}
371
372#[doc(hidden)]
375pub use ::commonware_formatting as __formatting;
376
377#[cfg(not(any(
380 commonware_stability_GAMMA,
381 commonware_stability_DELTA,
382 commonware_stability_EPSILON,
383 commonware_stability_RESERVED
384)))] #[macro_export]
386macro_rules! fixed_bytes {
387 ($s:tt) => {
388 const { $crate::sequence::FixedBytes::new($crate::__formatting::hex!($s)) }
389 };
390}
391
392#[macro_export]
394macro_rules! NZDuration {
395 ($val:expr) => {
396 $crate::NonZeroDuration::new_panic($val)
398 };
399}
400
401#[cfg(test)]
402mod tests {
403 use super::*;
404 use crate::TestRng;
405 use commonware_formatting::hex;
406 use num_bigint::BigUint;
407 use rand::RngExt as _;
408
409 #[test]
410 fn test_union() {
411 assert_eq!(union(&[], &[]), Vec::<u8>::new());
413
414 assert_eq!(union(&[], &hex!("0x010203")), hex!("0x010203"));
416
417 assert_eq!(
419 union(&hex!("0x010203"), &hex!("0x040506")),
420 hex!("0x010203040506")
421 );
422 }
423
424 #[test]
425 fn test_max() {
426 const UNEQUAL: usize = max(3, 7);
427 const REVERSED: usize = max(7, 3);
428 const EQUAL: usize = max(5, 5);
429 const ZERO: usize = max(0, 0);
430 const LARGEST: usize = max(usize::MAX, 0);
431 assert_eq!(UNEQUAL, 7);
432 assert_eq!(REVERSED, 7);
433 assert_eq!(EQUAL, 5);
434 assert_eq!(ZERO, 0);
435 assert_eq!(LARGEST, usize::MAX);
436 assert_eq!(max(0, usize::MAX), usize::MAX);
437 }
438
439 #[test]
440 fn test_union_unique() {
441 let namespace = b"namespace";
442 let msg = b"message";
443
444 let length_encoding = vec![0b0000_1001];
445 let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
446 expected.extend_from_slice(&length_encoding);
447 expected.extend_from_slice(namespace);
448 expected.extend_from_slice(msg);
449
450 let result = union_unique(namespace, msg);
451 assert_eq!(result, expected);
452 assert_eq!(result.len(), result.capacity());
453 }
454
455 #[test]
456 fn test_union_unique_zero_length() {
457 let namespace = b"";
458 let msg = b"message";
459
460 let length_encoding = vec![0];
461 let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
462 expected.extend_from_slice(&length_encoding);
463 expected.extend_from_slice(msg);
464
465 let result = union_unique(namespace, msg);
466 assert_eq!(result, expected);
467 assert_eq!(result.len(), result.capacity());
468 }
469
470 #[test]
471 fn test_union_unique_long_length() {
472 let namespace = &b"n".repeat(256);
474 let msg = b"message";
475
476 let length_encoding = vec![0b1000_0000, 0b0000_0010];
477 let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
478 expected.extend_from_slice(&length_encoding);
479 expected.extend_from_slice(namespace);
480 expected.extend_from_slice(msg);
481
482 let result = union_unique(namespace, msg);
483 assert_eq!(result, expected);
484 assert_eq!(result.len(), result.capacity());
485 }
486
487 #[test]
488 fn test_modulo() {
489 assert_eq!(modulo(&[], 1), 0);
491
492 assert_eq!(modulo(&hex!("0x01"), 1), 0);
494
495 assert_eq!(modulo(&hex!("0x010203"), 10), 1);
497
498 for i in 0..100 {
500 let mut rng = TestRng::new(i);
501 let bytes: [u8; 32] = rng.random();
502
503 let n = 11u64;
505 let big_modulo = BigUint::from_bytes_be(&bytes) % n;
506 let utils_modulo = modulo(&bytes, n);
507 assert_eq!(big_modulo, BigUint::from(utils_modulo));
508
509 let n = 11_111u64;
511 let big_modulo = BigUint::from_bytes_be(&bytes) % n;
512 let utils_modulo = modulo(&bytes, n);
513 assert_eq!(big_modulo, BigUint::from(utils_modulo));
514
515 let n = 0xDFFFFFFFFFFFFFFD;
517 let big_modulo = BigUint::from_bytes_be(&bytes) % n;
518 let utils_modulo = modulo(&bytes, n);
519 assert_eq!(big_modulo, BigUint::from(utils_modulo));
520 }
521 }
522
523 #[test]
524 #[should_panic]
525 fn test_modulo_zero_panics() {
526 modulo(&hex!("0x010203"), 0);
527 }
528
529 #[test]
530 fn test_non_zero_macros_compile_time() {
531 assert_eq!(NZUsize!(1).get(), 1);
534 assert_eq!(NZU8!(2).get(), 2);
535 assert_eq!(NZU16!(3).get(), 3);
536 assert_eq!(NZU32!(4).get(), 4);
537 assert_eq!(NZU64!(5).get(), 5);
538
539 const _: core::num::NonZeroUsize = NZUsize!(1);
541 const _: core::num::NonZeroU8 = NZU8!(2);
542 const _: core::num::NonZeroU16 = NZU16!(3);
543 const _: core::num::NonZeroU32 = NZU32!(4);
544 const _: core::num::NonZeroU64 = NZU64!(5);
545 }
546
547 #[test]
548 fn test_non_zero_macros_runtime() {
549 let one_usize: usize = 1;
551 let two_u8: u8 = 2;
552 let three_u16: u16 = 3;
553 let four_u32: u32 = 4;
554 let five_u64: u64 = 5;
555
556 assert_eq!(NZUsize!(one_usize).get(), 1);
557 assert_eq!(NZU8!(two_u8).get(), 2);
558 assert_eq!(NZU16!(three_u16).get(), 3);
559 assert_eq!(NZU32!(four_u32).get(), 4);
560 assert_eq!(NZU64!(five_u64).get(), 5);
561
562 let zero_usize: usize = 0;
564 let zero_u8: u8 = 0;
565 let zero_u16: u16 = 0;
566 let zero_u32: u32 = 0;
567 let zero_u64: u64 = 0;
568
569 assert!(std::panic::catch_unwind(|| NZUsize!(zero_usize)).is_err());
570 assert!(std::panic::catch_unwind(|| NZU8!(zero_u8)).is_err());
571 assert!(std::panic::catch_unwind(|| NZU16!(zero_u16)).is_err());
572 assert!(std::panic::catch_unwind(|| NZU32!(zero_u32)).is_err());
573 assert!(std::panic::catch_unwind(|| NZU64!(zero_u64)).is_err());
574
575 assert!(std::panic::catch_unwind(|| NZDuration!(Duration::ZERO)).is_err());
577 assert_eq!(
578 NZDuration!(Duration::from_secs(1)).get(),
579 Duration::from_secs(1)
580 );
581 }
582
583 #[test]
584 fn test_non_zero_duration() {
585 assert!(NonZeroDuration::new(Duration::ZERO).is_none());
587
588 let duration = Duration::from_millis(100);
590 let nz_duration = NonZeroDuration::new(duration).unwrap();
591 assert_eq!(nz_duration.get(), duration);
592 assert_eq!(Duration::from(nz_duration), duration);
593
594 assert!(std::panic::catch_unwind(|| NonZeroDuration::new_panic(Duration::ZERO)).is_err());
596
597 let d1 = NonZeroDuration::new(Duration::from_millis(100)).unwrap();
599 let d2 = NonZeroDuration::new(Duration::from_millis(200)).unwrap();
600 assert!(d1 < d2);
601 }
602
603 #[test]
604 fn test_participant_constructors() {
605 assert_eq!(Participant::new(0).get(), 0);
606 assert_eq!(Participant::new(42).get(), 42);
607 assert_eq!(Participant::from_usize(0).get(), 0);
608 assert_eq!(Participant::from_usize(42).get(), 42);
609 assert_eq!(Participant::from_usize(u32::MAX as usize).get(), u32::MAX);
610 }
611
612 #[test]
613 #[should_panic(expected = "participant index exceeds u32::MAX")]
614 fn test_participant_from_usize_overflow() {
615 Participant::from_usize((u32::MAX as usize) + 1);
616 }
617
618 #[test]
619 fn test_participant_display() {
620 assert_eq!(format!("{}", Participant::new(0)), "0");
621 assert_eq!(format!("{}", Participant::new(42)), "42");
622 assert_eq!(format!("{}", Participant::new(1000)), "1000");
623 }
624
625 #[test]
626 fn test_participant_ordering() {
627 assert!(Participant::new(0) < Participant::new(1));
628 assert!(Participant::new(5) < Participant::new(10));
629 assert!(Participant::new(10) > Participant::new(5));
630 assert_eq!(Participant::new(42), Participant::new(42));
631 }
632
633 #[test]
634 fn test_participant_encode_decode() {
635 use commonware_codec::{DecodeExt, Encode};
636
637 let cases = vec![0u32, 1, 127, 128, 255, 256, u32::MAX];
638 for value in cases {
639 let participant = Participant::new(value);
640 let encoded = participant.encode();
641 assert_eq!(encoded.len(), participant.encode_size());
642 let decoded = Participant::decode(encoded).unwrap();
643 assert_eq!(participant, decoded);
644 }
645 }
646
647 #[cfg(feature = "arbitrary")]
648 mod conformance {
649 use super::*;
650 use commonware_codec::conformance::CodecConformance;
651
652 commonware_conformance::conformance_tests! {
653 CodecConformance<Participant>,
654 }
655 }
656}