Skip to main content

async_flow/model/
port_id.rs

1// This is free and unencumbered software released into the public domain.
2
3/// A input or output port identifier.
4#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
7pub enum PortId {
8    Input(InputPortId),
9    Output(OutputPortId),
10}
11
12impl PortId {
13    pub fn as_isize(&self) -> isize {
14        match self {
15            PortId::Input(id) => id.0,
16            PortId::Output(id) => id.0,
17        }
18    }
19
20    pub fn as_usize(&self) -> usize {
21        self.as_isize() as _
22    }
23}
24
25impl TryFrom<isize> for PortId {
26    type Error = &'static str;
27
28    fn try_from(id: isize) -> Result<Self, Self::Error> {
29        if id < 0 {
30            Ok(Self::Input(InputPortId(id)))
31        } else if id > 0 {
32            Ok(Self::Output(OutputPortId(id)))
33        } else {
34            Err("Port IDs cannot be zero")
35        }
36    }
37}
38
39impl From<InputPortId> for PortId {
40    fn from(input: InputPortId) -> Self {
41        PortId::Input(input)
42    }
43}
44
45impl From<OutputPortId> for PortId {
46    fn from(input: OutputPortId) -> Self {
47        PortId::Output(input)
48    }
49}
50
51impl Into<isize> for PortId {
52    fn into(self) -> isize {
53        self.as_isize()
54    }
55}
56
57impl Into<usize> for PortId {
58    fn into(self) -> usize {
59        self.as_usize()
60    }
61}
62
63impl core::fmt::Display for PortId {
64    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
65        match self {
66            PortId::Input(id) => write!(f, "{}", id),
67            PortId::Output(id) => write!(f, "{}", id),
68        }
69    }
70}
71
72/// An input port identifier.
73#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
74#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
75pub struct InputPortId(pub(crate) isize);
76
77impl InputPortId {
78    #[doc(hidden)]
79    pub fn index(&self) -> usize {
80        self.0.unsigned_abs() - 1
81    }
82}
83
84impl TryFrom<isize> for InputPortId {
85    type Error = &'static str;
86
87    fn try_from(id: isize) -> Result<Self, Self::Error> {
88        if id < 0 {
89            Ok(InputPortId(id))
90        } else {
91            Err("Input port IDs must be negative integers")
92        }
93    }
94}
95
96impl Into<isize> for InputPortId {
97    fn into(self) -> isize {
98        self.0
99    }
100}
101
102impl Into<usize> for InputPortId {
103    fn into(self) -> usize {
104        self.0.unsigned_abs()
105    }
106}
107
108impl core::fmt::Display for InputPortId {
109    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
110        write!(f, "{}", self.0)
111    }
112}
113
114/// An output port identifier.
115#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
117pub struct OutputPortId(pub(crate) isize);
118
119impl OutputPortId {
120    #[doc(hidden)]
121    pub fn index(&self) -> usize {
122        (self.0 as usize) - 1
123    }
124}
125
126impl TryFrom<isize> for OutputPortId {
127    type Error = &'static str;
128
129    fn try_from(input: isize) -> Result<Self, Self::Error> {
130        if input > 0 {
131            Ok(OutputPortId(input))
132        } else {
133            Err("Output port IDs must be positive integers")
134        }
135    }
136}
137
138impl Into<isize> for OutputPortId {
139    fn into(self) -> isize {
140        self.0
141    }
142}
143
144impl Into<usize> for OutputPortId {
145    fn into(self) -> usize {
146        self.0 as usize
147    }
148}
149
150impl core::fmt::Display for OutputPortId {
151    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
152        write!(f, "{}", self.0)
153    }
154}