1use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Serialize, Deserialize)]
8pub enum LabelSide {
9 #[default]
10 Top,
11 Center,
12 Bottom,
13}
14
15#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Serialize, Deserialize)]
17pub enum Role {
18 #[default]
19 Accent0,
20 Accent1,
21 Accent2,
22 Accent3,
23 Accent4,
24 Accent5,
25 Accent6,
26 Accent7,
27 Accent8,
28}
29
30#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Serialize, Deserialize)]
31pub enum PinDir {
32 #[default]
33 Input,
34 InOut,
35 Output,
36}
37
38#[derive(Clone, Copy, PartialEq, Eq, Hash, Default, Debug, Serialize, Deserialize)]
41pub enum PinSide {
42 #[default]
43 West,
44 East,
45}
46
47impl PinSide {
48 #[must_use]
49 pub fn flip(self) -> Self {
50 match self {
51 Self::West => Self::East,
52 Self::East => Self::West,
53 }
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
64 fn defaults_are_the_meaningful_zeros() {
65 assert_eq!(Role::default(), Role::Accent0);
66 assert_eq!(LabelSide::default(), LabelSide::Top);
67 assert_eq!(PinDir::default(), PinDir::Input);
68 assert_eq!(PinSide::default(), PinSide::West);
69 }
70
71 #[test]
72 fn flipping_a_side_is_an_involution() {
73 for side in [PinSide::West, PinSide::East] {
74 assert_ne!(side.flip(), side);
75 assert_eq!(side.flip().flip(), side);
76 }
77 }
78
79 #[test]
82 fn serde_names_are_stable() {
83 fn name<T: Serialize>(value: &T) -> String {
84 serde_json::to_string(value).expect("value enums serialize infallibly")
85 }
86
87 let roles = [
88 Role::Accent0,
89 Role::Accent1,
90 Role::Accent2,
91 Role::Accent3,
92 Role::Accent4,
93 Role::Accent5,
94 Role::Accent6,
95 Role::Accent7,
96 Role::Accent8,
97 ];
98 for (i, role) in roles.into_iter().enumerate() {
99 assert_eq!(name(&role), format!("\"Accent{i}\""));
100 }
101
102 assert_eq!(name(&LabelSide::Top), "\"Top\"");
103 assert_eq!(name(&LabelSide::Center), "\"Center\"");
104 assert_eq!(name(&LabelSide::Bottom), "\"Bottom\"");
105
106 assert_eq!(name(&PinDir::Input), "\"Input\"");
107 assert_eq!(name(&PinDir::InOut), "\"InOut\"");
108 assert_eq!(name(&PinDir::Output), "\"Output\"");
109
110 assert_eq!(name(&PinSide::West), "\"West\"");
111 assert_eq!(name(&PinSide::East), "\"East\"");
112 }
113}