Skip to main content

blockworx/document/
pin_type.rs

1use serde::{Deserialize, Serialize};
2
3/// The signal direction of a pin/port, stored from the pin's point of view.
4///
5/// Rendering draws an arrowhead on the pin stub: `Input` points the head at
6/// the owning shape's edge, `Output` points it away, and `InOut` draws no
7/// arrow. When the same `PinPort` is rendered as a *port* (on the block's
8/// internals) the sense is flipped, so use [`PinType::flipped`] there.
9#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, Serialize, Deserialize)]
10pub enum PinType {
11    Input,
12    Output,
13    #[default]
14    InOut,
15}
16
17impl PinType {
18    /// The opposite sense, used when a pin is rendered as a port. `InOut`
19    /// has no sense, so it is unchanged.
20    pub fn flipped(self) -> Self {
21        match self {
22            PinType::Input => PinType::Output,
23            PinType::Output => PinType::Input,
24            PinType::InOut => PinType::InOut,
25        }
26    }
27
28    /// Next type in the cycle used by the I/O Pin tool: `InOut` → Input →
29    /// Output → `InOut`.
30    pub fn cycle(self) -> Self {
31        match self {
32            PinType::InOut => PinType::Input,
33            PinType::Input => PinType::Output,
34            PinType::Output => PinType::InOut,
35        }
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn default_is_inout() {
45        assert_eq!(PinType::default(), PinType::InOut);
46    }
47
48    #[test]
49    fn flip_swaps_input_output_and_leaves_inout() {
50        assert_eq!(PinType::Input.flipped(), PinType::Output);
51        assert_eq!(PinType::Output.flipped(), PinType::Input);
52        assert_eq!(PinType::InOut.flipped(), PinType::InOut);
53    }
54
55    #[test]
56    fn cycle_visits_all_three_and_returns() {
57        let k = PinType::default();
58        let k = k.cycle();
59        assert_eq!(k, PinType::Input);
60        let k = k.cycle();
61        assert_eq!(k, PinType::Output);
62        let k = k.cycle();
63        assert_eq!(k, PinType::InOut);
64    }
65}