Skip to main content

ferrocat_icu/
ast.rs

1/// Parsed ICU message.
2#[derive(Debug, Clone, PartialEq, Eq, Default)]
3pub struct IcuMessage {
4    /// Top-level AST nodes in source order.
5    pub nodes: Vec<IcuNode>,
6}
7
8/// Distinguishes cardinal and ordinal plural forms.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub enum IcuPluralKind {
11    /// Cardinal plural categories such as `one` and `other`.
12    Cardinal,
13    /// Ordinal plural categories such as `one`, `two`, `few`, and `other`.
14    Ordinal,
15}
16
17/// A selector branch inside a plural or select expression.
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct IcuOption {
20    /// Raw selector label such as `one`, `other`, or `=0`.
21    pub selector: String,
22    /// Nested nodes rendered when the selector matches.
23    pub value: Vec<IcuNode>,
24}
25
26/// AST node emitted by the ICU parser.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum IcuNode {
29    /// Literal text content.
30    Literal(String),
31    /// Simple argument substitution such as `{name}`.
32    Argument {
33        /// Argument identifier.
34        name: String,
35    },
36    /// Number formatter such as `{count, number}`.
37    Number {
38        /// Argument identifier.
39        name: String,
40        /// Optional formatter style segment.
41        style: Option<String>,
42    },
43    /// Date formatter such as `{createdAt, date, short}`.
44    Date {
45        /// Argument identifier.
46        name: String,
47        /// Optional formatter style segment.
48        style: Option<String>,
49    },
50    /// Time formatter such as `{createdAt, time, short}`.
51    Time {
52        /// Argument identifier.
53        name: String,
54        /// Optional formatter style segment.
55        style: Option<String>,
56    },
57    /// List formatter such as `{items, list}`.
58    List {
59        /// Argument identifier.
60        name: String,
61        /// Optional formatter style segment.
62        style: Option<String>,
63    },
64    /// Duration formatter such as `{elapsed, duration}`.
65    Duration {
66        /// Argument identifier.
67        name: String,
68        /// Optional formatter style segment.
69        style: Option<String>,
70    },
71    /// Relative-time "ago" formatter.
72    Ago {
73        /// Argument identifier.
74        name: String,
75        /// Optional formatter style segment.
76        style: Option<String>,
77    },
78    /// Name formatter.
79    Name {
80        /// Argument identifier.
81        name: String,
82        /// Optional formatter style segment.
83        style: Option<String>,
84    },
85    /// Select expression with labeled branches.
86    Select {
87        /// Argument identifier.
88        name: String,
89        /// Available selector branches.
90        options: Vec<IcuOption>,
91    },
92    /// Cardinal or ordinal plural expression.
93    Plural {
94        /// Argument identifier.
95        name: String,
96        /// Whether the plural expression is cardinal or ordinal.
97        kind: IcuPluralKind,
98        /// Parsed plural offset value.
99        offset: u32,
100        /// Available plural branches.
101        options: Vec<IcuOption>,
102    },
103    /// `#` placeholder inside plural branches.
104    Pound,
105    /// Rich-text style tag with nested children.
106    Tag {
107        /// Tag name without angle brackets.
108        name: String,
109        /// Nested child nodes inside the tag body.
110        children: Vec<Self>,
111    },
112}