protoflow_core/
port_id.rs

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