1use std::{fmt::Display, str::FromStr};
2
3use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ValueRef};
4
5use crate::PdgError;
6
7#[derive(Debug, Copy, Clone)]
9pub enum ValueType {
10 WeightedAverage,
12 BestLimit,
14 BranchingRatio,
16 PdgEvaluation,
18 PdgLimit,
20 ExtraBelow,
22 ExtraAbove,
24 FittedData,
26 FittedDecayRate,
28 Estimate,
30 DefaultEvaluation,
32 Internal,
34}
35
36impl ValueType {
37 #[must_use]
39 pub const fn to_code(&self) -> &'static str {
40 match self {
41 Self::WeightedAverage => "AC",
42 Self::BestLimit => "L",
43 Self::BranchingRatio => "D",
44 Self::PdgEvaluation => "V",
45 Self::PdgLimit => "OL",
46 Self::ExtraBelow => "OM",
47 Self::ExtraAbove => "ON",
48 Self::FittedData => "FC",
49 Self::FittedDecayRate => "DR",
50 Self::Estimate => "E",
51 Self::DefaultEvaluation => "O",
52 Self::Internal => "DV",
53 }
54 }
55}
56
57impl Display for ValueType {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(
60 f,
61 "{}",
62 match self {
63 Self::WeightedAverage => "Weighted average",
64 Self::BestLimit => "Best limit",
65 Self::BranchingRatio => "Branching ratio",
66 Self::PdgEvaluation => "PDG evaluation",
67 Self::PdgLimit => "PDG limit",
68 Self::ExtraBelow => "Extra below",
69 Self::ExtraAbove => "Extra above",
70 Self::FittedData => "Fitted data",
71 Self::FittedDecayRate => "Fitted decay rate",
72 Self::Estimate => "Estimate",
73 Self::DefaultEvaluation => "Default evaluation",
74 Self::Internal => "Internal",
75 }
76 )
77 }
78}
79
80impl FromStr for ValueType {
81 type Err = PdgError;
82
83 fn from_str(s: &str) -> Result<Self, Self::Err> {
84 match s {
85 "AC" => Ok(Self::WeightedAverage),
86 "L" => Ok(Self::BestLimit),
87 "D" => Ok(Self::BranchingRatio),
88 "V" => Ok(Self::PdgEvaluation),
89 "OL" => Ok(Self::PdgLimit),
90 "OM" => Ok(Self::ExtraBelow),
91 "ON" => Ok(Self::ExtraAbove),
92 "FC" => Ok(Self::FittedData),
93 "DR" => Ok(Self::FittedDecayRate),
94 "E" => Ok(Self::Estimate),
95 "O" => Ok(Self::DefaultEvaluation),
96 "DV" => Ok(Self::Internal),
97 _ => Err(PdgError::ParseValueType(s.to_string())),
98 }
99 }
100}
101
102impl FromSql for ValueType {
103 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
104 match value {
105 ValueRef::Text(bytes) => {
106 let s =
107 std::str::from_utf8(bytes).map_err(|err| FromSqlError::Other(Box::new(err)))?;
108 Self::from_str(s).map_err(|err| FromSqlError::Other(Box::new(err)))
109 }
110 _ => Err(FromSqlError::InvalidType),
111 }
112 }
113}
114
115#[derive(Debug, Copy, Clone, PartialEq, Eq)]
117pub enum LimitType {
118 UpperLimit,
120 LowerLimit,
122 Range,
124 RangeExclusion,
126}
127
128impl LimitType {
129 #[must_use]
131 pub const fn to_code(&self) -> &'static str {
132 match self {
133 Self::UpperLimit => "U",
134 Self::LowerLimit => "L",
135 Self::Range => "R",
136 Self::RangeExclusion => "X",
137 }
138 }
139}
140
141impl Display for LimitType {
142 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
143 write!(
144 f,
145 "{}",
146 match self {
147 Self::UpperLimit => "Upper limit",
148 Self::LowerLimit => "Lower limit",
149 Self::Range => "Range",
150 Self::RangeExclusion => "Range exclusion",
151 }
152 )
153 }
154}
155
156impl FromStr for LimitType {
157 type Err = PdgError;
158
159 fn from_str(s: &str) -> Result<Self, Self::Err> {
160 match s {
161 "U" => Ok(Self::UpperLimit),
162 "L" => Ok(Self::LowerLimit),
163 "R" => Ok(Self::Range),
164 "X" => Ok(Self::RangeExclusion),
165 _ => Err(PdgError::ParseLimitType(s.to_string())),
166 }
167 }
168}
169
170impl FromSql for LimitType {
171 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
172 match value {
173 ValueRef::Text(bytes) => {
174 let s =
175 std::str::from_utf8(bytes).map_err(|err| FromSqlError::Other(Box::new(err)))?;
176 Self::from_str(s).map_err(|err| FromSqlError::Other(Box::new(err)))
177 }
178 _ => Err(FromSqlError::InvalidType),
179 }
180 }
181}
182
183#[derive(Debug, Copy, Clone, PartialEq, Eq)]
185pub enum DataType {
186 ElectricDipoleMoment,
188 MagneticMoment,
190 CPViolationParameter,
192 MassDifference,
194 FormFactor,
196 MeanLifetime,
198 SlopeParameter,
200 FullWidth,
202 Mass,
204 CouplingConstantRatio,
206 DecayParameter,
208 Lifetime,
210 ExclusiveBranchingFraction,
212 ExclusiveBranchingFraction1,
214 ExclusiveBranchingFraction2,
216 ExclusiveBranchingFraction3,
218 ExclusiveBranchingFraction4,
220 ExclusiveBranchingFraction5,
222 InclusiveBranchingFraction,
224 InclusiveBranchingFraction1,
226 InclusiveBranchingFraction2,
228 InclusiveBranchingFraction3,
230 InclusiveBranchingFraction4,
232 InclusiveBranchingFraction5,
234 BranchingRatio,
236 Particle,
238 Searches,
240 Section,
242 Other,
244}
245
246impl FromSql for DataType {
247 fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
248 match value {
249 ValueRef::Text(bytes) => {
250 let s =
251 std::str::from_utf8(bytes).map_err(|err| FromSqlError::Other(Box::new(err)))?;
252 Self::from_str(s).map_err(|err| FromSqlError::Other(Box::new(err)))
253 }
254 _ => Err(FromSqlError::InvalidType),
255 }
256 }
257}
258
259impl DataType {
260 #[must_use]
262 pub const fn to_code(&self) -> &'static str {
263 match self {
264 Self::ElectricDipoleMoment => "e",
265 Self::MagneticMoment => "m",
266 Self::CPViolationParameter => "v",
267 Self::MassDifference => "D",
268 Self::FormFactor => "f",
269 Self::MeanLifetime => "g",
270 Self::SlopeParameter => "s",
271 Self::FullWidth => "G",
272 Self::Mass => "M",
273 Self::CouplingConstantRatio => "c",
274 Self::DecayParameter => "d",
275 Self::Lifetime => "T",
276 Self::ExclusiveBranchingFraction => "BFX",
277 Self::ExclusiveBranchingFraction1 => "BFX1",
278 Self::ExclusiveBranchingFraction2 => "BFX2",
279 Self::ExclusiveBranchingFraction3 => "BFX3",
280 Self::ExclusiveBranchingFraction4 => "BFX4",
281 Self::ExclusiveBranchingFraction5 => "BFX5",
282 Self::InclusiveBranchingFraction => "BFI",
283 Self::InclusiveBranchingFraction1 => "BFI1",
284 Self::InclusiveBranchingFraction2 => "BFI2",
285 Self::InclusiveBranchingFraction3 => "BFI3",
286 Self::InclusiveBranchingFraction4 => "BFI4",
287 Self::InclusiveBranchingFraction5 => "BFI5",
288 Self::BranchingRatio => "BR",
289 Self::Particle => "PART",
290 Self::Searches => "SRCH",
291 Self::Section => "SEC",
292 Self::Other => "",
293 }
294 }
295
296 #[must_use]
298 pub const fn is_branching_fraction(&self) -> bool {
299 matches!(
300 self,
301 Self::ExclusiveBranchingFraction
302 | Self::ExclusiveBranchingFraction1
303 | Self::ExclusiveBranchingFraction2
304 | Self::ExclusiveBranchingFraction3
305 | Self::ExclusiveBranchingFraction4
306 | Self::ExclusiveBranchingFraction5
307 | Self::InclusiveBranchingFraction
308 | Self::InclusiveBranchingFraction1
309 | Self::InclusiveBranchingFraction2
310 | Self::InclusiveBranchingFraction3
311 | Self::InclusiveBranchingFraction4
312 | Self::InclusiveBranchingFraction5
313 )
314 }
315
316 #[must_use]
318 pub const fn is_particle_property(&self) -> bool {
319 !matches!(
320 self,
321 Self::BranchingRatio | Self::Particle | Self::Searches | Self::Section | Self::Other
322 ) && !self.is_branching_fraction()
323 }
324}
325
326impl Display for DataType {
327 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
328 write!(
329 f,
330 "{}",
331 match self {
332 Self::ElectricDipoleMoment => "Electric dipole moment",
333 Self::MagneticMoment => "Magnetic moment",
334 Self::CPViolationParameter => "CP violation parameter",
335 Self::MassDifference => "Mass difference",
336 Self::FormFactor => "Form factor",
337 Self::MeanLifetime => "Mean lifetime",
338 Self::SlopeParameter => "Slope parameter",
339 Self::FullWidth => "Width",
340 Self::Mass => "Mass",
341 Self::CouplingConstantRatio => "Coupling constant ratio",
342 Self::DecayParameter => "Decay parameter",
343 Self::Lifetime => "Lifetime",
344 Self::ExclusiveBranchingFraction
345 | Self::ExclusiveBranchingFraction1
346 | Self::ExclusiveBranchingFraction2
347 | Self::ExclusiveBranchingFraction3
348 | Self::ExclusiveBranchingFraction4
349 | Self::ExclusiveBranchingFraction5 => "Exclusive branching fraction",
350 Self::InclusiveBranchingFraction
351 | Self::InclusiveBranchingFraction1
352 | Self::InclusiveBranchingFraction2
353 | Self::InclusiveBranchingFraction3
354 | Self::InclusiveBranchingFraction4
355 | Self::InclusiveBranchingFraction5 => "Inclusive branching fraction",
356 Self::BranchingRatio => "Branching ratio",
357 Self::Particle => "Particle",
358 Self::Searches => "Searches",
359 Self::Section => "Section",
360 Self::Other => "Other",
361 }
362 )
363 }
364}
365
366impl FromStr for DataType {
367 type Err = PdgError;
368
369 fn from_str(s: &str) -> Result<Self, Self::Err> {
370 match s {
371 "e" => Ok(Self::ElectricDipoleMoment),
372 "m" => Ok(Self::MagneticMoment),
373 "v" => Ok(Self::CPViolationParameter),
374 "D" => Ok(Self::MassDifference),
375 "f" => Ok(Self::FormFactor),
376 "g" => Ok(Self::MeanLifetime),
377 "s" => Ok(Self::SlopeParameter),
378 "G" => Ok(Self::FullWidth),
379 "M" => Ok(Self::Mass),
380 "c" => Ok(Self::CouplingConstantRatio),
381 "d" => Ok(Self::DecayParameter),
382 "T" => Ok(Self::Lifetime),
383 "BFX" => Ok(Self::ExclusiveBranchingFraction),
384 "BFX1" => Ok(Self::ExclusiveBranchingFraction1),
385 "BFX2" => Ok(Self::ExclusiveBranchingFraction2),
386 "BFX3" => Ok(Self::ExclusiveBranchingFraction3),
387 "BFX4" => Ok(Self::ExclusiveBranchingFraction4),
388 "BFX5" => Ok(Self::ExclusiveBranchingFraction5),
389 "BFI" => Ok(Self::InclusiveBranchingFraction),
390 "BFI1" => Ok(Self::InclusiveBranchingFraction1),
391 "BFI2" => Ok(Self::InclusiveBranchingFraction2),
392 "BFI3" => Ok(Self::InclusiveBranchingFraction3),
393 "BFI4" => Ok(Self::InclusiveBranchingFraction4),
394 "BFI5" => Ok(Self::InclusiveBranchingFraction5),
395 "BR" => Ok(Self::BranchingRatio),
396 "PART" => Ok(Self::Particle),
397 "SRCH" => Ok(Self::Searches),
398 "SEC" => Ok(Self::Section),
399 "" => Ok(Self::Other),
400 _ => Err(PdgError::ParseDataType(s.to_string())),
401 }
402 }
403}