1use derive_more::Display as DeriveMoreDisplay;
29use serde::{Serialize};
30use std::collections::BTreeMap;
31use crate::error::MacSysInfoError;
32use crate::parse::{parse_sysctl_value, ParseAsType};
33use crate::generated_sysctl_keys::SysctlKey;
34use crate::structs::CpuArchitectureInfo;
35
36#[derive(Debug, Serialize, DeriveMoreDisplay)]
38#[allow(non_camel_case_types)]
39pub enum CpuFeaturesInfo {
40 AppleSi(AppleSiCpuFeaturesInfo),
43 x86_64(X86_64CpuFeaturesInfo),
46}
47
48impl CpuFeaturesInfo {
49
50 pub(crate) fn new(sysinfo: &BTreeMap<String, String>) -> Result<Self, MacSysInfoError> {
52 let arch = CpuArchitectureInfo::determine_architecture(sysinfo)?;
53 if arch.is_x86_64() {
54 Ok(
55 CpuFeaturesInfo::x86_64(
56 X86_64CpuFeaturesInfo::new(sysinfo)?
57 )
58 )
59 } else {
60 Ok(
61 CpuFeaturesInfo::AppleSi(
62 AppleSiCpuFeaturesInfo::new(sysinfo)?
63 )
64 )
65 }
66 }
67
68 pub fn get_apple_si_features(self) -> AppleSiCpuFeaturesInfo {
70 if let CpuFeaturesInfo::AppleSi(val) = self {
71 val
72 } else {
73 panic!("Not Apple Silicon!")
74 }
75 }
76
77 pub fn get_x86_features(self) -> X86_64CpuFeaturesInfo {
79 if let CpuFeaturesInfo::x86_64(val) = self {
80 val
81 } else {
82 panic!("Not x86!")
83 }
84 }
85}
86
87#[derive(Debug, Serialize, DeriveMoreDisplay)]
89pub struct AppleSiCpuFeaturesInfo {
90 }
92
93impl AppleSiCpuFeaturesInfo {
94
95 pub(crate) fn new(_sysinfo: &BTreeMap<String, String>) -> Result<Self, MacSysInfoError> {
97 Ok(AppleSiCpuFeaturesInfo {})
98 }
99}
100
101#[derive(Debug, Serialize, DeriveMoreDisplay)]
103#[display(fmt = "X86CpuFeatures (\n\
104\x20 mmx: {},\n\
105\x20 sse: {},\n\
106\x20 sse2: {},\n\
107\x20 sse3: {},\n\
108\x20 sse4_1: {},\n\
109\x20 sse4_2: {},\n\
110\x20 aes: {},\n\
111\x20 avx1_0: {},\n\
112\x20 avx2_0: {},\n\
113\x20 avx512f: {},\n\
114\x20 avx512cd: {},\n\
115\x20 avx512dq: {},\n\
116\x20 avx512bw: {},\n\
117\x20 avx512vl: {},\n\
118\x20 avx512ifma: {},\n\
119\x20 avx512vbmi: {},\n\
120)", mmx, sse, sse2, sse3, sse4_1, sse4_2, aes, avx1_0, avx2_0, avx512f, avx512cd, avx512dq, avx512bw, avx512vl, avx512ifma, avx512vbmi)]
121#[allow(non_camel_case_types)]
122pub struct X86_64CpuFeaturesInfo {
123 mmx: bool,
124 sse: bool,
125 sse2: bool,
126 sse3: bool,
127 sse4_1: bool,
128 sse4_2: bool,
129 aes: bool,
130 avx1_0: bool,
131 avx2_0: bool,
132 avx512f: bool,
133 avx512cd: bool,
134 avx512dq: bool,
135 avx512bw: bool,
136 avx512vl: bool,
137 avx512ifma: bool,
138 avx512vbmi: bool,
139}
140
141impl X86_64CpuFeaturesInfo {
142
143 pub(crate) fn new(sysinfo: &BTreeMap<String, String>) -> Result<Self, MacSysInfoError> {
145 let x = X86_64CpuFeaturesInfo {
146 mmx: parse_sysctl_value(
147 "mmx",
148 SysctlKey::HwOptionalMmx,
149 sysinfo,
150 ParseAsType::Bool)?
151 .get_bool(),
152 sse: parse_sysctl_value(
153 "sse",
154 SysctlKey::HwOptionalSse,
155 sysinfo,
156 ParseAsType::Bool)?
157 .get_bool(),
158 sse2: parse_sysctl_value(
159 "sse2",
160 SysctlKey::HwOptionalSse2,
161 sysinfo,
162 ParseAsType::Bool)?
163 .get_bool(),
164 sse3: parse_sysctl_value(
165 "sse3",
166 SysctlKey::HwOptionalSse3,
167 sysinfo,
168 ParseAsType::Bool)?
169 .get_bool(),
170 sse4_1: parse_sysctl_value(
171 "sse4_1",
172 SysctlKey::HwOptionalSse4_1,
173 sysinfo,
174 ParseAsType::Bool)?
175 .get_bool(),
176 sse4_2: parse_sysctl_value(
177 "sse4_2",
178 SysctlKey::HwOptionalSse4_2,
179 sysinfo,
180 ParseAsType::Bool)?
181 .get_bool(),
182 aes: parse_sysctl_value(
183 "aes",
184 SysctlKey::HwOptionalAes,
185 sysinfo,
186 ParseAsType::Bool)?
187 .get_bool(),
188 avx1_0: parse_sysctl_value(
189 "avx1_0",
190 SysctlKey::HwOptionalAvx1_0,
191 sysinfo,
192 ParseAsType::Bool)?
193 .get_bool(),
194 avx2_0: parse_sysctl_value(
195 "avx2_0",
196 SysctlKey::HwOptionalAvx2_0,
197 sysinfo,
198 ParseAsType::Bool)?
199 .get_bool(),
200 avx512f: parse_sysctl_value(
201 "avx512f",
202 SysctlKey::HwOptionalAvx512f,
203 sysinfo,
204 ParseAsType::Bool)?
205 .get_bool(),
206 avx512cd: parse_sysctl_value(
207 "avx512cd",
208 SysctlKey::HwOptionalAvx512cd,
209 sysinfo,
210 ParseAsType::Bool)?
211 .get_bool(),
212 avx512dq: parse_sysctl_value(
213 "avx512dq",
214 SysctlKey::HwOptionalAvx512dq,
215 sysinfo,
216 ParseAsType::Bool)?
217 .get_bool(),
218 avx512bw: parse_sysctl_value(
219 "avx512bw",
220 SysctlKey::HwOptionalAvx512bw,
221 sysinfo,
222 ParseAsType::Bool)?
223 .get_bool(),
224 avx512vl: parse_sysctl_value(
225 "avx512vl",
226 SysctlKey::HwOptionalAvx512vl,
227 sysinfo,
228 ParseAsType::Bool)?
229 .get_bool(),
230 avx512ifma: parse_sysctl_value(
231 "avx512ifma",
232 SysctlKey::HwOptionalAvx512ifma,
233 sysinfo,
234 ParseAsType::Bool)?
235 .get_bool(),
236 avx512vbmi: parse_sysctl_value(
237 "avx512vbmi",
238 SysctlKey::HwOptionalAvx512vbmi,
239 sysinfo,
240 ParseAsType::Bool)?
241 .get_bool(),
242 };
243 Ok(x)
244 }
245
246 pub fn mmx(&self) -> bool {
248 self.mmx
249 }
250 pub fn sse(&self) -> bool {
252 self.sse
253 }
254 pub fn sse2(&self) -> bool {
256 self.sse2
257 }
258 pub fn sse3(&self) -> bool {
260 self.sse3
261 }
262 pub fn sse4_1(&self) -> bool {
264 self.sse4_1
265 }
266 pub fn sse4_2(&self) -> bool {
268 self.sse4_2
269 }
270 pub fn aes(&self) -> bool {
272 self.aes
273 }
274 pub fn avx1_0(&self) -> bool {
276 self.avx1_0
277 }
278 pub fn avx2_0(&self) -> bool {
280 self.avx2_0
281 }
282 pub fn avx512f(&self) -> bool {
284 self.avx512f
285 }
286 pub fn avx512cd(&self) -> bool {
288 self.avx512cd
289 }
290 pub fn avx512dq(&self) -> bool {
292 self.avx512dq
293 }
294 pub fn avx512bw(&self) -> bool {
296 self.avx512bw
297 }
298 pub fn avx512vl(&self) -> bool {
300 self.avx512vl
301 }
302 pub fn avx512ifma(&self) -> bool {
304 self.avx512ifma
305 }
306 pub fn avx512vbmi(&self) -> bool {
308 self.avx512vbmi
309 }
310}
311