protoflow_core/
port_id.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// This is free and unencumbered software released into the public domain.

use crate::prelude::{fmt, TryFrom};

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
pub enum PortID {
    Input(InputPortID),
    Output(OutputPortID),
}

impl PortID {
    pub fn as_isize(&self) -> isize {
        match self {
            PortID::Input(id) => id.0,
            PortID::Output(id) => id.0,
        }
    }

    pub fn as_usize(&self) -> usize {
        self.as_isize() as _
    }
}

impl TryFrom<isize> for PortID {
    type Error = &'static str;

    fn try_from(id: isize) -> Result<PortID, &'static str> {
        if id < 0 {
            Ok(Self::Input(InputPortID(id)))
        } else if id > 0 {
            Ok(Self::Output(OutputPortID(id)))
        } else {
            Err("Port ID cannot be zero")
        }
    }
}

impl From<InputPortID> for PortID {
    fn from(port_id: InputPortID) -> PortID {
        PortID::Input(port_id)
    }
}

impl From<OutputPortID> for PortID {
    fn from(port_id: OutputPortID) -> PortID {
        PortID::Output(port_id)
    }
}

impl From<PortID> for isize {
    fn from(port_id: PortID) -> isize {
        port_id.as_isize()
    }
}

impl From<PortID> for usize {
    fn from(port_id: PortID) -> usize {
        port_id.as_usize()
    }
}

impl fmt::Display for PortID {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            PortID::Input(id) => write!(f, "{}", id),
            PortID::Output(id) => write!(f, "{}", id),
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct InputPortID(pub(crate) isize);

impl InputPortID {
    #[doc(hidden)]
    pub fn index(&self) -> usize {
        self.0.unsigned_abs() - 1
    }
}

impl TryFrom<isize> for InputPortID {
    type Error = &'static str;

    fn try_from(id: isize) -> Result<InputPortID, &'static str> {
        if id < 0 {
            Ok(InputPortID(id))
        } else {
            Err("Input port IDs must be negative integers")
        }
    }
}

impl From<InputPortID> for isize {
    fn from(id: InputPortID) -> isize {
        id.0
    }
}

impl From<InputPortID> for usize {
    fn from(id: InputPortID) -> usize {
        id.0.unsigned_abs()
    }
}

impl fmt::Display for InputPortID {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OutputPortID(pub(crate) isize);

impl OutputPortID {
    #[doc(hidden)]
    pub fn index(&self) -> usize {
        (self.0 as usize) - 1
    }
}

impl TryFrom<isize> for OutputPortID {
    type Error = &'static str;

    fn try_from(id: isize) -> Result<OutputPortID, &'static str> {
        if id > 0 {
            Ok(OutputPortID(id))
        } else {
            Err("Output port IDs must be positive integers")
        }
    }
}

impl From<OutputPortID> for isize {
    fn from(id: OutputPortID) -> isize {
        id.0
    }
}

impl From<OutputPortID> for usize {
    fn from(id: OutputPortID) -> usize {
        id.0 as usize
    }
}

impl fmt::Display for OutputPortID {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}