1use crate::section::{
2 parse_cont_record, parse_dir_record, parse_head_record, parse_text_record,
3 ParseEndfSectionError,
4};
5use std::fs::File;
6use std::io::{BufRead, BufReader};
7
8#[derive(Debug, PartialEq)]
9pub struct Mt451 {
10 za: f64,
11 awr: f64,
12 lrp: i32,
13 lfi: u32,
14 nlib: u32,
15 nmod: u32,
16 elis: f64,
17 sta: u32,
18 lis: u32,
19 liso: u32,
20 nfor: u32,
21 awi: f64,
22 emax: f64,
23 lrel: u32,
24 nsub: u32,
25 nver: u32,
26 temp: f64,
27 ldrv: u32,
28 nwd: u32,
29 nxc: u32,
30 zsymam: String,
31 alab: String,
32 edate: String,
33 auth: String,
34 pref: String,
35 ddate: String,
36 rdate: String,
37 endate: String,
38 hsub: String,
39 description: String,
40 directories: Vec<Directory>,
41}
42
43#[derive(Debug, Eq, PartialEq)]
44pub struct Directory {
45 mf: u32,
46 mt: u32,
47 nc: u32,
48 modn: u32,
49}
50
51impl Directory {
52 pub fn new(mf: u32, mt: u32, nc: u32, modn: u32) -> Directory {
53 Directory { mf, mt, nc, modn }
54 }
55
56 pub fn mf(&self) -> u32 {
57 self.mf
58 }
59
60 pub fn mt(&self) -> u32 {
61 self.mt
62 }
63
64 pub fn nc(&self) -> u32 {
65 self.nc
66 }
67
68 pub fn modn(&self) -> u32 {
69 self.modn
70 }
71}
72
73impl Mt451 {
74 pub fn parse(reader: &mut BufReader<File>) -> Result<Mt451, ParseEndfSectionError> {
75 let mut record = String::with_capacity(82);
76 reader.read_line(&mut record).unwrap();
77 let head = parse_head_record(&record)?;
78 record.clear();
79 reader.read_line(&mut record).unwrap();
80 let cont1 = parse_cont_record(&record)?;
81 record.clear();
82 reader.read_line(&mut record).unwrap();
83 let cont2 = parse_cont_record(&record)?;
84 record.clear();
85 reader.read_line(&mut record).unwrap();
86 let cont3 = parse_cont_record(&record)?;
87 record.clear();
88 reader.read_line(&mut record).unwrap();
89 let text1 = parse_text_record(&record)?;
90 record.clear();
91 reader.read_line(&mut record).unwrap();
92 let text2 = parse_text_record(&record)?;
93 let mut hsub = String::with_capacity((66 + 1) * 3);
94 for _ in 1..=3 {
95 record.clear();
96 reader.read_line(&mut record).unwrap();
97 let text = parse_text_record(&record)?;
98 hsub.push_str(text.hl());
99 hsub.push('\n');
100 }
101 let nwd = cont3.n1();
102 let mut description = String::with_capacity(82 * nwd as usize);
103 for _ in 1..=nwd {
104 record.clear();
105 reader.read_line(&mut record).unwrap();
106 let text = parse_text_record(&record)?;
107 description.push_str(text.hl());
108 description.push('\n');
109 }
110 let nxc = cont3.n2();
111 let mut directories: Vec<Directory> = Vec::with_capacity(nxc as usize);
112 for _ in 1..=nxc {
113 record.clear();
114 reader.read_line(&mut record).unwrap();
115 let dir = parse_dir_record(&record)?;
116 let directory = Directory::new(
117 dir.l1() as u32,
118 dir.l2() as u32,
119 dir.n1() as u32,
120 dir.n2() as u32,
121 );
122 directories.push(directory);
123 }
124 Ok(Mt451 {
125 za: head.za(),
126 awr: head.awr(),
127 lrp: head.l1() as i32,
128 lfi: head.l2() as u32,
129 nlib: head.n1() as u32,
130 nmod: head.n2() as u32,
131 elis: cont1.c1(),
132 sta: cont1.c2() as u32,
133 lis: cont1.l1() as u32,
134 liso: cont1.l2() as u32,
135 nfor: cont1.n2() as u32,
136 awi: cont2.c1(),
137 emax: cont2.c2(),
138 lrel: cont2.l1() as u32,
139 nsub: cont2.n1() as u32,
140 nver: cont2.n2() as u32,
141 temp: cont3.c1(),
142 ldrv: cont3.l1() as u32,
143 nwd: cont3.n1() as u32,
144 nxc: cont3.n2() as u32,
145 zsymam: String::from(&text1.hl()[..11]),
146 alab: String::from(&text1.hl()[11..22]),
147 edate: String::from(&text1.hl()[22..32]),
148 auth: String::from(&text1.hl()[33..66]),
149 pref: String::from(&text2.hl()[1..22]),
150 ddate: String::from(&text2.hl()[22..32]),
151 rdate: String::from(&text2.hl()[33..43]),
152 endate: String::from(&text2.hl()[55..63]),
153 hsub,
154 description,
155 directories,
156 })
157 }
158 pub fn za(&self) -> f64 {
159 self.za
160 }
161 pub fn awr(&self) -> f64 {
162 self.awr
163 }
164 pub fn lrp(&self) -> i32 {
165 self.lrp
166 }
167 pub fn lfi(&self) -> u32 {
168 self.lfi
169 }
170 pub fn nlib(&self) -> u32 {
171 self.nlib
172 }
173 pub fn nmod(&self) -> u32 {
174 self.nmod
175 }
176 pub fn elis(&self) -> f64 {
177 self.elis
178 }
179 pub fn sta(&self) -> u32 {
180 self.sta
181 }
182 pub fn lis(&self) -> u32 {
183 self.lis
184 }
185 pub fn liso(&self) -> u32 {
186 self.liso
187 }
188 pub fn nfor(&self) -> u32 {
189 self.nfor
190 }
191 pub fn awi(&self) -> f64 {
192 self.awi
193 }
194 pub fn emax(&self) -> f64 {
195 self.emax
196 }
197 pub fn lrel(&self) -> u32 {
198 self.lrel
199 }
200 pub fn nsub(&self) -> u32 {
201 self.nsub
202 }
203 pub fn nver(&self) -> u32 {
204 self.nver
205 }
206 pub fn temp(&self) -> f64 {
207 self.temp
208 }
209 pub fn ldrv(&self) -> u32 {
210 self.ldrv
211 }
212 pub fn nwd(&self) -> u32 {
213 self.nwd
214 }
215 pub fn nxc(&self) -> u32 {
216 self.nxc
217 }
218 pub fn zsymam(&self) -> &String {
219 &self.zsymam
220 }
221 pub fn alab(&self) -> &String {
222 &self.alab
223 }
224 pub fn edate(&self) -> &String {
225 &self.edate
226 }
227 pub fn auth(&self) -> &String {
228 &self.auth
229 }
230 pub fn pref(&self) -> &String {
231 &self.pref
232 }
233 pub fn ddate(&self) -> &String {
234 &self.ddate
235 }
236 pub fn rdate(&self) -> &String {
237 &self.rdate
238 }
239 pub fn endate(&self) -> &String {
240 &self.endate
241 }
242 pub fn hsub(&self) -> &String {
243 &self.hsub
244 }
245 pub fn description(&self) -> &String {
246 &self.description
247 }
248 pub fn directories(&self) -> &Vec<Directory> {
249 &self.directories
250 }
251}
252
253#[cfg(test)]
254mod tests {
255 use super::*;
256
257 #[test]
258 fn parse_valid_head() {
259 let file = File::open("resources/mt451.endf").unwrap();
260 let mut reader = BufReader::new(file);
261 let section = Mt451::parse(&mut reader).unwrap();
262 assert!((1.234_567_89 - section.za()).abs() < 1e-8);
263 assert!((1.23456e+1 - section.awr()).abs() < 1e-8);
264 assert_eq!(0, section.lrp());
265 assert_eq!(1, section.lfi());
266 assert_eq!(2, section.nlib());
267 assert_eq!(3, section.nmod());
268 }
269
270 #[test]
271 fn parse_valid_cont() {
272 let file = File::open("resources/mt451.endf").unwrap();
273 let mut reader = BufReader::new(file);
274 let section = Mt451::parse(&mut reader).unwrap();
275 assert!((1.2345e-12 - section.elis()).abs() < 1e-20);
276 assert_eq!(1, section.sta());
277 assert_eq!(4, section.lis());
278 assert_eq!(5, section.liso());
279 assert_eq!(6, section.nfor());
280 assert!((9.876_543_21 - section.awi()).abs() < 1e-8);
281 assert!((9.876_543e+2 - section.emax()).abs() < 1e-6);
282 assert_eq!(7, section.lrel());
283 assert_eq!(8, section.nsub());
284 assert_eq!(9, section.nver());
285 assert!((9.87654e+21 - section.temp()).abs() < 1e-13);
286 assert_eq!(10, section.ldrv());
287 assert_eq!(1, section.nwd());
288 assert_eq!(1, section.nxc());
289 }
290
291 #[test]
292 fn parse_valid_text() {
293 let file = File::open("resources/mt451.endf").unwrap();
294 let mut reader = BufReader::new(file);
295 let section = Mt451::parse(&mut reader).unwrap();
296 assert_eq!(&String::from("123-Xx-456M"), section.zsymam());
297 assert_eq!(&String::from("LABO_______"), section.alab());
298 assert_eq!(&String::from("EVAL-MMMYY"), section.edate());
299 assert_eq!(
300 &String::from("AUTHOR(S)________________________"),
301 section.auth()
302 );
303 assert_eq!(&String::from("Reference____________"), section.pref());
304 assert_eq!(&String::from("DIST-MMMYY"), section.ddate());
305 assert_eq!(&String::from("REVX-MMMYY"), section.rdate());
306 assert_eq!(&String::from("yyyymmdd"), section.endate());
307 }
308
309 #[test]
310 fn parse_valid_hsub() {
311 let file = File::open("resources/mt451.endf").unwrap();
312 let mut reader = BufReader::new(file);
313 let section = Mt451::parse(&mut reader).unwrap();
314 assert_eq!(
315 &String::from(
316 "----NLIB/NVER MATERIAL XXXX REVISION X \n\
317 -----SUB-LIBRARY IDENTIFIER \n\
318 ------ENDF-6 FORMAT \n"
319 ),
320 section.hsub()
321 );
322 }
323
324 #[test]
325 fn parse_valid_description() {
326 let file = File::open("resources/mt451.endf").unwrap();
327 let mut reader = BufReader::new(file);
328 let section = Mt451::parse(&mut reader).unwrap();
329 assert_eq!(
330 &String::from("******************************************************************\n"),
331 section.description()
332 );
333 }
334
335 #[test]
336 fn parse_valid_directories() {
337 let file = File::open("resources/mt451.endf").unwrap();
338 let mut reader = BufReader::new(file);
339 let section = Mt451::parse(&mut reader).unwrap();
340 let mut directories: Vec<Directory> = Vec::new();
341 directories.push(Directory::new(1, 451, 11, 1));
342 assert_eq!(&directories, section.directories());
343 }
344}