1use std::fmt::Display;
2
3use rusqlite::Row;
4
5use crate::{LimitType, PdgFootnote, PdgId};
6
7#[derive(Clone, Debug)]
9pub struct PdgReference {
10 pub document_id: String,
12 pub publication_name: Option<String>,
14 pub publication_year: Option<isize>,
16 pub doi: Option<String>,
18 pub inspire_id: Option<String>,
20 pub title: Option<String>,
22}
23
24#[derive(Clone, Debug)]
26pub struct PdgMeasurement {
27 pub pdgid: PdgId,
29 pub reference: PdgReference,
31 pub event_count: Option<String>,
33 pub confidence_level: Option<f64>,
35 pub place: Option<String>,
37 pub technique: Option<String>,
39 pub charge: Option<String>,
41 pub changebar: bool,
43 pub comment: Option<String>,
45 pub sort: isize,
47 pub values: Vec<PdgMeasurementValue>,
49 pub footnotes: Vec<PdgFootnote>,
51 pub(crate) id: isize,
52}
53
54impl TryFrom<&Row<'_>> for PdgMeasurement {
55 type Error = rusqlite::Error;
56
57 fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
58 Ok(Self {
59 id: row.get(0)?,
60 pdgid: row.get(1)?,
61 event_count: row.get(2)?,
62 confidence_level: row.get(3)?,
63 place: row.get(4)?,
64 technique: row.get(5)?,
65 charge: row.get(6)?,
66 changebar: row.get(7)?,
67 comment: row.get(8)?,
68 sort: row.get(9)?,
69 reference: PdgReference {
70 document_id: row.get(10)?,
71 publication_name: row.get(11)?,
72 publication_year: row.get(12)?,
73 doi: row.get(13)?,
74 inspire_id: row.get(14)?,
75 title: row.get(15)?,
76 },
77 values: Vec::new(),
78 footnotes: Vec::new(),
79 })
80 }
81}
82
83#[derive(Clone, Debug)]
85pub struct PdgMeasurementValue {
86 pub column_name: Option<String>,
88 pub value_text: Option<String>,
90 pub unit_text: Option<String>,
92 pub display_value_text: Option<String>,
94 pub display_power_of_ten: Option<isize>,
96 pub display_in_percent: Option<bool>,
98 pub limit_type: Option<LimitType>,
100 pub used_in_average: bool,
102 pub used_in_fit: bool,
104 pub value: Option<f64>,
106 pub error_positive: Option<f64>,
108 pub error_negative: Option<f64>,
110 pub stat_error_positive: Option<f64>,
112 pub stat_error_negative: Option<f64>,
114 pub syst_error_positive: Option<f64>,
116 pub syst_error_negative: Option<f64>,
118 pub sort: isize,
120}
121
122impl TryFrom<&Row<'_>> for PdgMeasurementValue {
123 type Error = rusqlite::Error;
124
125 fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
126 Ok(Self {
127 column_name: row.get(0)?,
128 value_text: row.get(1)?,
129 unit_text: row.get(2)?,
130 display_value_text: row.get(3)?,
131 display_power_of_ten: row.get(4)?,
132 display_in_percent: row.get(5)?,
133 limit_type: row.get(6)?,
134 used_in_average: row.get(7)?,
135 used_in_fit: row.get(8)?,
136 value: row.get(9)?,
137 error_positive: row.get(10)?,
138 error_negative: row.get(11)?,
139 stat_error_positive: row.get(12)?,
140 stat_error_negative: row.get(13)?,
141 syst_error_positive: row.get(14)?,
142 syst_error_negative: row.get(15)?,
143 sort: row.get(16)?,
144 })
145 }
146}
147
148impl Display for PdgMeasurementValue {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 write!(
151 f,
152 "{}",
153 self.display_value_text
154 .clone()
155 .unwrap_or_else(|| "NULL".to_string())
156 )?;
157 if self.display_in_percent.unwrap_or_default() {
158 write!(f, "%")?;
159 } else if self.display_power_of_ten.unwrap_or_default() != 0 {
160 write!(f, "E{}", self.display_power_of_ten.unwrap_or_default())?;
161 }
162 if let Some(unit_text) = &self.unit_text
163 && !unit_text.is_empty()
164 {
165 write!(f, " {unit_text}")?;
166 }
167
168 Ok(())
169 }
170}