crystal_cif_io/grammar/numeric_values/
integer.rs

1use std::fmt::Display;
2
3use winnow::{
4    combinator::{alt, repeat},
5    Parser,
6};
7
8use crate::grammar::SyntacticUnit;
9
10use super::unsigned_integer::UnsignedInteger;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
13pub struct Integer(pub i32);
14
15impl Display for Integer {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> core::fmt::Result {
17        <i32 as Display>::fmt(&self.0, f)
18    }
19}
20
21impl std::ops::Deref for Integer {
22    type Target = i32;
23
24    fn deref(&self) -> &Self::Target {
25        &self.0
26    }
27}
28
29impl SyntacticUnit for Integer {
30    type ParseResult = Self;
31
32    type FormatOutput = i32;
33
34    fn parser(input: &mut &str) -> winnow::prelude::PResult<Self::ParseResult> {
35        (repeat(0..=1, alt(('+', '-'))), UnsignedInteger::parser)
36            .map(|(sign, u): (String, UnsignedInteger)| {
37                if sign.contains('-') {
38                    Integer(-(*u as i32))
39                } else {
40                    Integer(*u as i32)
41                }
42            })
43            .parse_next(input)
44    }
45
46    fn formatted_output(&self) -> Self::FormatOutput {
47        self.0
48    }
49}
50
51impl From<u32> for Integer {
52    fn from(value: u32) -> Self {
53        Integer(value as i32)
54    }
55}