Skip to main content

async_flow/model/
inputs.rs

1// This is free and unencumbered software released into the public domain.
2
3use super::{InputPortId, PortId};
4use core::{
5    any::type_name,
6    marker::PhantomData,
7    ops::Bound,
8    sync::atomic::{AtomicIsize, Ordering},
9};
10
11/// A one-shot input port of type `T`.
12///
13/// Note that `Input` implements `Copy`, whereas `Output` doesn't.
14pub type Input<T> = Inputs<T, 1, 0>;
15
16/// An input port of type `T`.
17///
18/// Note that `Inputs` implements `Copy`, whereas `Outputs` doesn't.
19#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
20pub struct Inputs<T, const MAX: isize = -1, const MIN: isize = 0>(InputPortId, PhantomData<T>);
21
22impl<T, const MAX: isize, const MIN: isize> Default for Inputs<T, MAX, MIN> {
23    fn default() -> Self {
24        static COUNTER: AtomicIsize = AtomicIsize::new(-1);
25        let id = COUNTER.fetch_sub(1, Ordering::AcqRel);
26        Self(InputPortId(id), PhantomData)
27    }
28}
29
30impl<T, const MAX: isize, const MIN: isize> core::fmt::Debug for Inputs<T, MAX, MIN> {
31    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32        f.debug_tuple(&alloc::format!("Inputs<{}>", type_name::<T>()))
33            .field(&self.0)
34            .finish()
35    }
36}
37
38impl<T, const MAX: isize, const MIN: isize> Inputs<T, MAX, MIN> {
39    pub fn id(&self) -> InputPortId {
40        self.0
41    }
42
43    /// Returns the cardinality of this connection.
44    pub fn cardinality() -> (Bound<usize>, Bound<usize>) {
45        assert!(MIN >= 0);
46        assert!(MAX >= -1);
47        use Bound::*;
48        match (MIN, MAX) {
49            (min, -1) => (Included(min as _), Unbounded),
50            (min, max) => (Included(min as _), Included(max as _)),
51        }
52    }
53}
54
55impl<T, const MAX: isize, const MIN: isize> Into<InputPortId> for &Inputs<T, MAX, MIN> {
56    fn into(self) -> InputPortId {
57        self.0
58    }
59}
60
61impl<T, const MAX: isize, const MIN: isize> Into<PortId> for &Inputs<T, MAX, MIN> {
62    fn into(self) -> PortId {
63        self.0.into()
64    }
65}