1use num::traits::SaturatingAdd;
6use sponge_hash_aes256::DEFAULT_DIGEST_SIZE;
7use std::{
8 num::NonZeroUsize,
9 sync::atomic::{AtomicUsize, Ordering},
10};
11use tinyvec::{ArrayVec, TinyVec};
12
13pub const MAX_SNAIL_LEVEL: u8 = 4u8;
19
20pub const MAX_DIGEST_SIZE: usize = 8usize * DEFAULT_DIGEST_SIZE;
22
23pub type Digest = TinyVec<[u8; DEFAULT_DIGEST_SIZE]>;
25
26pub struct Aborted;
28
29pub struct Flag(AtomicUsize);
35
36pub struct UpdateError;
38
39const STATUS_RUNNING: usize = 0usize;
41const STATUS_STOPPED: usize = 1usize;
42const STATUS_ABORTED: usize = 2usize;
43
44impl Flag {
45 #[inline(always)]
49 pub fn running(&self) -> bool {
50 self.0.load(Ordering::Relaxed) == STATUS_RUNNING
51 }
52
53 #[inline]
55 pub fn stop_process(&self) -> Result<(), UpdateError> {
56 self.try_update(STATUS_STOPPED)
57 }
58
59 #[inline]
61 pub fn abort_process(&self) -> Result<(), UpdateError> {
62 self.try_update(STATUS_ABORTED)
63 }
64
65 #[inline(always)]
66 fn try_update(&self, new_state: usize) -> Result<(), UpdateError> {
67 match self.0.compare_exchange(STATUS_RUNNING, new_state, Ordering::AcqRel, Ordering::Acquire) {
68 Ok(_) => Ok(()),
69 Err(previous_state) => match previous_state == new_state {
70 true => Ok(()),
71 false => Err(UpdateError),
72 },
73 }
74 }
75}
76
77impl Default for Flag {
78 #[inline]
79 fn default() -> Self {
80 Self(AtomicUsize::new(STATUS_RUNNING))
81 }
82}
83
84pub trait TinyVecEx {
89 fn with_length(length: usize) -> Self;
90}
91
92impl<const N: usize, T: Copy + Default> TinyVecEx for TinyVec<[T; N]> {
93 #[inline(always)]
94 fn with_length(length: usize) -> Self {
95 if length <= N {
96 TinyVec::Inline(ArrayVec::from_array_len([T::default(); N], length))
97 } else {
98 TinyVec::Heap(vec![T::default(); length])
99 }
100 }
101}
102
103#[inline(always)]
109pub fn increment<T: SaturatingAdd + From<u8>>(counter: &mut T) {
110 *counter = counter.saturating_add(&T::from(1u8));
111}
112
113#[inline]
115pub fn get_capacity(thread_count: &NonZeroUsize) -> usize {
116 let capacity = thread_count.get().saturating_mul(2usize).saturating_add(1usize);
117 if capacity > isize::MAX as usize {
118 capacity
119 } else {
120 capacity.next_power_of_two()
121 }
122}
123
124#[macro_export]
130macro_rules! print_error {
131 ($args:ident, $fmt:literal $(,$arg:expr)*$(,)?) => {
132 if !$args.quiet {
133 eprintln!(concat!("[sponge256sum] ", $fmt) $(, $arg)*);
134 }
135 };
136}