async_flow/model/
outputs.rs1use core::{
4 any::type_name,
5 marker::PhantomData,
6 ops::Bound,
7 sync::atomic::{AtomicIsize, Ordering},
8};
9
10pub type OutputId = isize;
11
12pub type Output<T> = Outputs<T, 1, 0>;
16
17#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
21pub struct Outputs<T, const MAX: isize = -1, const MIN: isize = 0>(OutputId, PhantomData<T>);
22
23impl<T, const MAX: isize, const MIN: isize> Default for Outputs<T, MAX, MIN> {
24 fn default() -> Self {
25 static COUNTER: AtomicIsize = AtomicIsize::new(1);
26 let id = COUNTER.fetch_add(1, Ordering::AcqRel);
27 Self(id, PhantomData)
28 }
29}
30
31impl<T, const MAX: isize, const MIN: isize> core::fmt::Debug for Outputs<T, MAX, MIN> {
32 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33 f.debug_tuple(&alloc::format!("Outputs<{}>", type_name::<T>()))
34 .field(&self.0)
35 .finish()
36 }
37}
38
39impl<T, const MAX: isize, const MIN: isize> Outputs<T, MAX, MIN> {
40 pub fn id(&self) -> OutputId {
41 self.0
42 }
43
44 pub fn cardinality() -> (Bound<usize>, Bound<usize>) {
46 assert!(MIN >= 0);
47 assert!(MAX >= -1);
48 use Bound::*;
49 match (MIN, MAX) {
50 (min, -1) => (Included(min as _), Unbounded),
51 (min, max) => (Included(min as _), Included(max as _)),
52 }
53 }
54}
55
56impl<T, const MAX: isize, const MIN: isize> Into<OutputId> for Outputs<T, MAX, MIN> {
57 fn into(self) -> OutputId {
58 self.0
59 }
60}