castep_model_core/parser/msi_parser/state_machine/
model_attributes_parser.rs

1use std::collections::HashMap;
2
3use nalgebra::Vector3;
4use nom::{
5    branch::alt,
6    bytes::complete::tag,
7    character::complete::{char, space0, space1},
8    combinator::recognize,
9    sequence::{delimited, preceded, separated_pair, terminated, tuple},
10    IResult,
11};
12
13use crate::parser::{decimal, float};
14
15use super::{Analyzed, MsiParser};
16
17pub fn hashmap_attrs<'a>(attributes: &[&'a str]) -> HashMap<String, &'a str> {
18    let mut hashmap: HashMap<String, &str> = HashMap::new();
19    attributes.iter().for_each(|item| {
20        let (attr_str, key) = MsiParser::<Analyzed>::get_attribute_type(item).unwrap();
21        hashmap.insert(key.into(), attr_str);
22    });
23    hashmap
24}
25
26pub fn parse_cry_display(input: &str) -> IResult<&str, (u32, u32)> {
27    let (rest, value_str) = preceded(
28        tuple((tag("I"), space1, tag("CRY/DISPLAY"), space1)),
29        delimited(
30            char('('),
31            separated_pair(decimal, space1, decimal),
32            char(')'),
33        ),
34    )(input)?;
35    let value = (
36        value_str.0.parse::<u32>().unwrap(),
37        value_str.1.parse::<u32>().unwrap(),
38    );
39    Ok((rest, value))
40}
41
42pub fn parse_periodic_type(input: &str) -> IResult<&str, u8> {
43    let (rest, value_str) = preceded(
44        tuple((tag("I"), space1, tag("PeriodicType"), space1)),
45        decimal,
46    )(input)?;
47    Ok((rest, value_str.parse::<u8>().unwrap()))
48}
49
50pub fn parse_space_group(input: &str) -> IResult<&str, &str> {
51    preceded(
52        tuple((tag("C"), space1, tag("SpaceGroup"), space1)),
53        delimited(
54            char('"'),
55            recognize(separated_pair(decimal, space1, decimal)),
56            char('"'),
57        ),
58    )(input)
59}
60
61pub fn parse_cry_tolerance(input: &str) -> IResult<&str, f64> {
62    let (rest, value_str) = preceded(
63        tuple((tag("D"), space1, tag("CRY/TOLERANCE"), space1)),
64        float,
65    )(input)?;
66    Ok((rest, value_str.parse::<f64>().unwrap()))
67}
68
69pub fn parse_vector(input: &str) -> IResult<&str, Vector3<f64>> {
70    let (rest, vec_str): (&str, (&str, &str, &str)) = preceded(
71        tuple((
72            tag("D"),
73            space1,
74            alt((tag("A3"), tag("B3"), tag("C3"))),
75            space1,
76        )),
77        delimited(
78            char('('),
79            tuple((
80                terminated(alt((float, decimal)), space0),
81                terminated(alt((float, decimal)), space0),
82                alt((float, decimal)),
83            )),
84            char(')'),
85        ),
86    )(input)?;
87    let (x, y, z) = vec_str;
88    let (x, y, z) = (
89        x.parse::<f64>().unwrap(),
90        y.parse::<f64>().unwrap(),
91        z.parse::<f64>().unwrap(),
92    );
93    let vec: [f64; 3] = [x, y, z];
94    Ok((rest, Vector3::from(vec)))
95}