mod error;
pub use error::EndfError;
mod integer;
pub use integer::{parse_endf_integer, ParseEndfIntegerError};
mod float;
pub use float::{parse_endf_float, ParseEndfFloatError};
mod records;
pub use records::{Cont, Intg, List, Tab1, Tab2, Text};
mod read;
pub use read::EndfReader;
pub fn parse_integer<R: AsRef<[u8]>>(record: R, column: usize) -> Result<i64, EndfError> {
assert!(column > 0);
assert!(column <= 6);
let start = (column - 1) * 11;
let stop = column * 11;
match record.as_ref().get(start..stop) {
Some(slice) => match parse_endf_integer(slice) {
Ok(integer) => Ok(integer),
Err(_) => Err(EndfError::Data),
},
None => Err(EndfError::Format),
}
}
pub fn parse_float<R: AsRef<[u8]>>(record: R, column: usize) -> Result<f64, EndfError> {
assert!(column > 0);
assert!(column <= 6);
let start = (column - 1) * 11;
let stop = column * 11;
match record.as_ref().get(start..stop) {
Some(slice) => match parse_endf_float(slice) {
Ok(float) => Ok(float),
Err(_) => Err(EndfError::Data),
},
None => Err(EndfError::Format),
}
}
pub fn parse_cont<R: AsRef<[u8]>>(record: R) -> Result<Cont, EndfError> {
let record = record.as_ref();
let c1 = parse_float(record, 1)?;
let c2 = parse_float(record, 2)?;
let l1 = parse_integer(record, 3)?;
let l2 = parse_integer(record, 4)?;
let n1 = parse_integer(record, 5)?;
let n2 = parse_integer(record, 6)?;
Ok(Cont(c1, c2, l1, l2, n1, n2))
}
pub fn parse_text<R: AsRef<[u8]>>(record: R) -> Result<Text, EndfError> {
let record = record.as_ref();
match record.get(0..66) {
Some(slice) => match String::from_utf8(slice.to_vec()) {
Ok(hl) => Ok(Text(hl)),
Err(_) => Err(EndfError::Data),
},
None => Err(EndfError::Format),
}
}
type ControlNumbers = (i32, u32, u32, Option<u32>);
pub fn parse_control_numbers<R: AsRef<[u8]>>(record: R) -> Result<ControlNumbers, EndfError> {
let record = record.as_ref();
let mat = parse_material(record)?;
let mf = parse_file(record)?;
let mt = parse_section(record)?;
let ns = parse_sequence(record)?;
Ok((mat, mf, mt, ns))
}
pub fn parse_material<R: AsRef<[u8]>>(record: R) -> Result<i32, EndfError> {
let record = record.as_ref();
match record.get(66..70) {
Some(slice) => match parse_endf_integer(slice) {
Ok(integer) => Ok(integer as i32),
Err(_) => Err(EndfError::Data),
},
None => Err(EndfError::Format),
}
}
pub fn parse_file<R: AsRef<[u8]>>(record: R) -> Result<u32, EndfError> {
let record = record.as_ref();
match record.get(70..72) {
Some(slice) => match parse_endf_integer(slice) {
Ok(integer) => integer.try_into().map_err(|_| EndfError::Data),
Err(_) => Err(EndfError::Data),
},
None => Err(EndfError::Format),
}
}
pub fn parse_section<R: AsRef<[u8]>>(record: R) -> Result<u32, EndfError> {
let record = record.as_ref();
match record.get(72..75) {
Some(slice) => match parse_endf_integer(slice) {
Ok(integer) => integer.try_into().map_err(|_| EndfError::Data),
Err(_) => Err(EndfError::Data),
},
None => Err(EndfError::Format),
}
}
pub fn parse_sequence<R: AsRef<[u8]>>(record: R) -> Result<Option<u32>, EndfError> {
let record = record.as_ref();
match record.get(75..80) {
Some(slice) => match parse_endf_integer(slice) {
Ok(integer) => match integer.try_into() {
Ok(integer) => Ok(Some(integer)),
Err(_) => Err(EndfError::Data),
},
Err(_) => Err(EndfError::Data),
},
None => Ok(None),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn integer() {
let record =
" 1 -1 1234567890-1234567890 1 -1 12341212312345";
assert_eq!(parse_integer(record, 1).unwrap(), 1);
assert_eq!(parse_integer(record, 2).unwrap(), -1);
assert_eq!(parse_integer(record, 3).unwrap(), 1234567890);
assert_eq!(parse_integer(record, 4).unwrap(), -1234567890);
assert_eq!(parse_integer(record, 5).unwrap(), 1);
assert_eq!(parse_integer(record, 6).unwrap(), -1);
}
#[test]
fn float() {
let record =
" 1.23456789-1.23456789 1.35790+12-1.35790-12 2.4680E+13-2.4680E-1312341212312345";
assert_eq!(parse_float(record, 1).unwrap(), 1.23456789);
assert_eq!(parse_float(record, 2).unwrap(), -1.23456789);
assert_eq!(parse_float(record, 3).unwrap(), 1.35790E12);
assert_eq!(parse_float(record, 4).unwrap(), -1.35790E-12);
assert_eq!(parse_float(record, 5).unwrap(), 2.4680E+13);
assert_eq!(parse_float(record, 6).unwrap(), -2.4680E-13);
}
#[test]
fn controls() {
let record =
" 1.23456789-1.23456789 1 2 3 412341212312345";
let (mat, mf, mt, ns) = parse_control_numbers(record).unwrap();
assert_eq!(mat, 1234);
assert_eq!(mf, 12);
assert_eq!(mt, 123);
assert_eq!(ns, Some(12345));
}
#[test]
fn record() {
let record =
" 1.23456789-1.23456789 1 2 3 412341212312345";
let Cont(c1, c2, l1, l2, n1, n2) = parse_cont(record.as_bytes()).unwrap();
assert_eq!(c1, 1.23456789);
assert_eq!(c2, -1.23456789);
assert_eq!(l1, 1);
assert_eq!(l2, 2);
assert_eq!(n1, 3);
assert_eq!(n2, 4);
}
#[test]
fn material() {
let record =
" 1.23456789-1.23456789 1 2 3 412341212312345";
let mat = parse_material(record.as_bytes()).unwrap();
assert_eq!(mat, 1234);
}
#[test]
fn file() {
let record =
" 1.23456789-1.23456789 1 2 3 412341212312345";
let mf = parse_file(record.as_bytes()).unwrap();
assert_eq!(mf, 12);
}
#[test]
fn section() {
let record =
" 1.23456789-1.23456789 1 2 3 412341212312345";
let mt = parse_section(record.as_bytes()).unwrap();
assert_eq!(mt, 123);
}
#[test]
fn sequence_some() {
let record =
" 1.23456789-1.23456789 1 2 3 412341212312345";
let ns = parse_sequence(record.as_bytes()).unwrap();
assert_eq!(ns, Some(12345));
}
#[test]
fn sequence_none() {
let record = " 1.23456789-1.23456789 1 2 3 4123412123";
let ns = parse_sequence(record.as_bytes()).unwrap();
assert_eq!(ns, None);
}
}