1use indexmap::IndexMap;
2use num_bigint::BigInt;
3use std::fmt;
4use std::str::FromStr;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7pub struct DecimalInt(pub BigInt);
8
9impl DecimalInt {
10 pub fn new(value: impl AsRef<str>) -> Self {
11 let raw = value.as_ref();
12 let trimmed = raw.trim();
13 let parsed = BigInt::from_str(trimmed)
14 .unwrap_or_else(|_| panic!("invalid decimal integer literal: `{raw}`"));
15 Self(parsed)
16 }
17
18 pub fn as_bigint(&self) -> &BigInt {
19 &self.0
20 }
21
22 pub fn canonicalized(&self) -> Self {
23 canonicalize_decimal(self)
24 }
25}
26
27impl fmt::Display for DecimalInt {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 write!(f, "{}", self.0)
30 }
31}
32
33impl FromStr for DecimalInt {
34 type Err = num_bigint::ParseBigIntError;
35
36 fn from_str(s: &str) -> Result<Self, Self::Err> {
37 Ok(Self(BigInt::from_str(s.trim())?))
38 }
39}
40
41impl From<BigInt> for DecimalInt {
42 fn from(value: BigInt) -> Self {
43 Self(value)
44 }
45}
46
47impl From<DecimalInt> for BigInt {
48 fn from(value: DecimalInt) -> Self {
49 value.0
50 }
51}
52
53pub fn canonicalize_decimal(value: &DecimalInt) -> DecimalInt {
54 value.clone()
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub enum ValueIr {
59 Null,
60 Bool(bool),
61 Integer(DecimalInt),
62 Float(f64),
63 Text(TextValueIr),
64 Array(Vec<ValueIr>),
65 Tuple(Vec<ValueIr>),
66 Map(IndexMap<ObjectKeyIr, ValueIr>),
67}
68
69#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct TextValueIr {
71 pub value: String,
72 pub language: TextLanguageIr,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub enum TextLanguageIr {
77 Plain,
78 Implicit,
79 Tagged(String),
80}
81
82#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
83pub enum ObjectKeyIr {
84 String(String),
85 Integer(DecimalInt),
86 Tuple(Vec<ObjectKeyIr>),
87}