1#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Debug, Ord)]
2pub struct PyVersion {
3 pub major: u8,
4 pub minor: u8,
5 pub patch: u8, }
7
8impl PyVersion {
9 pub fn new(major: u8, minor: u8) -> Self {
10 Self {
11 major,
12 minor,
13 patch: 0,
14 }
15 }
16}
17
18impl Into<String> for PyVersion {
19 fn into(self) -> String {
20 format!("{}.{}.{}", self.major, self.minor, self.patch)
21 }
22}
23
24impl From<(u8, u8)> for PyVersion {
25 fn from(vers: (u8, u8)) -> Self {
26 Self {
27 major: vers.0,
28 minor: vers.1,
29 patch: 0,
30 }
31 }
32}
33
34impl From<(u8, u8, u8)> for PyVersion {
35 fn from(vers: (u8, u8, u8)) -> Self {
36 Self {
37 major: vers.0,
38 minor: vers.1,
39 patch: vers.2,
40 }
41 }
42}
43
44impl PyVersion {
45 const MAGIC_NUMBERS: &'static [(u32, PyVersion)] = &[
46 (
47 0x0A0D0C3B,
48 PyVersion {
49 major: 3,
50 minor: 0,
51 patch: 0,
52 },
53 ),
54 (
55 0x0A0D0C4F,
56 PyVersion {
57 major: 3,
58 minor: 1,
59 patch: 0,
60 },
61 ),
62 (
63 0x0A0D0C6C,
64 PyVersion {
65 major: 3,
66 minor: 2,
67 patch: 0,
68 },
69 ),
70 (
71 0x0A0D0C9E,
72 PyVersion {
73 major: 3,
74 minor: 3,
75 patch: 0,
76 },
77 ),
78 (
79 0x0A0D0CEE,
80 PyVersion {
81 major: 3,
82 minor: 4,
83 patch: 0,
84 },
85 ),
86 (
87 0x0A0D0D16,
88 PyVersion {
89 major: 3,
90 minor: 5,
91 patch: 0,
92 },
93 ),
94 (
95 0x0A0D0D33,
96 PyVersion {
97 major: 3,
98 minor: 6,
99 patch: 0,
100 },
101 ),
102 (
103 0x0A0D0D42,
104 PyVersion {
105 major: 3,
106 minor: 7,
107 patch: 0,
108 },
109 ),
110 (
111 0x0A0D0D55,
112 PyVersion {
113 major: 3,
114 minor: 8,
115 patch: 0,
116 },
117 ),
118 (
119 0x0A0D0D61,
120 PyVersion {
121 major: 3,
122 minor: 9,
123 patch: 0,
124 },
125 ),
126 (
127 0x0A0D0D6F,
128 PyVersion {
129 major: 3,
130 minor: 10,
131 patch: 0,
132 },
133 ),
134 (
135 0x0A0D0DA7,
136 PyVersion {
137 major: 3,
138 minor: 11,
139 patch: 0,
140 },
141 ),
142 (
143 0x0A0D0DCB,
144 PyVersion {
145 major: 3,
146 minor: 12,
147 patch: 0,
148 },
149 ),
150 (
151 0x0A0D0DF3,
152 PyVersion {
153 major: 3,
154 minor: 13,
155 patch: 0,
156 },
157 ),
158 ];
159
160 pub fn from_magic(magic: u32) -> Result<Self, crate::Error> {
161 Self::MAGIC_NUMBERS
162 .iter()
163 .find(|&&(num, _)| num == magic)
164 .map(|&(_, version)| version)
165 .ok_or(crate::Error::UnsupportedMagicNumber(magic))
166 }
167
168 pub fn to_magic(&self) -> Result<u32, crate::Error> {
169 Self::MAGIC_NUMBERS
170 .iter()
171 .find(|&&(_, ref version)| version == self)
172 .map(|&(num, _)| num)
173 .ok_or(crate::Error::UnsupportedPyVersion(self.clone()))
174 }
175}
176
177impl TryFrom<u32> for PyVersion {
178 type Error = crate::Error;
179
180 fn try_from(vers: u32) -> Result<Self, Self::Error> {
181 PyVersion::from_magic(vers)
182 }
183}
184
185impl TryFrom<PyVersion> for u32 {
186 type Error = crate::Error;
187
188 fn try_from(vers: PyVersion) -> Result<Self, Self::Error> {
189 vers.to_magic()
190 }
191}
192
193impl PartialEq<(u8, u8)> for PyVersion {
194 fn eq(&self, other: &(u8, u8)) -> bool {
195 self.major == other.0 && self.minor == other.1
196 }
197}
198
199impl PartialOrd<(u8, u8)> for PyVersion {
200 fn partial_cmp(&self, other: &(u8, u8)) -> Option<std::cmp::Ordering> {
201 Some(self.cmp(&PyVersion::new(other.0, other.1)))
202 }
203}
204
205impl std::fmt::Display for PyVersion {
206 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207 write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
208 }
209}