sway_ast/
literal.rs

1use crate::priv_prelude::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
4pub struct LitString {
5    pub span: Span,
6    pub parsed: String,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
10pub struct LitChar {
11    pub span: Span,
12    pub parsed: char,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
16pub struct LitInt {
17    pub span: Span,
18    pub parsed: BigUint,
19    pub ty_opt: Option<(LitIntType, Span)>,
20    /// True if this [LitInt] represents a `b256` hex literal
21    /// in a manually generated lexed tree.
22    ///
23    /// `b256` hex literals are not explicitly modeled in the
24    /// [Literal]. During parsing, they are parsed as [LitInt]
25    /// with [LitInt::ty_opt] set to `None`.
26    ///
27    /// To properly render `b256` manually created hex literals,
28    /// that are not backed by a [Span] in the source code,
29    /// we need this additional information, to distinguish
30    /// them from `u256` hex literals.
31    pub is_generated_b256: bool,
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
35pub enum LitIntType {
36    U8,
37    U16,
38    U32,
39    U64,
40    U256,
41    I8,
42    I16,
43    I32,
44    I64,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
48pub struct LitBool {
49    pub span: Span,
50    pub kind: LitBoolType,
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
54pub enum LitBoolType {
55    True,
56    False,
57}
58
59impl From<LitBoolType> for bool {
60    fn from(item: LitBoolType) -> Self {
61        match item {
62            LitBoolType::True => true,
63            LitBoolType::False => false,
64        }
65    }
66}
67
68#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash, Serialize, Deserialize)]
69pub enum Literal {
70    String(LitString),
71    Char(LitChar),
72    Int(LitInt),
73    Bool(LitBool),
74}
75
76impl Literal {
77    /// Friendly type name string of the [Literal] used for various reportings.
78    pub fn friendly_type_name(&self) -> &'static str {
79        use Literal::*;
80        match self {
81            String(_) => "str",
82            Char(_) => "char",
83            Int(lit_int) => {
84                if lit_int.is_generated_b256 {
85                    "b256"
86                } else {
87                    lit_int
88                        .ty_opt
89                        .as_ref()
90                        .map_or("numeric", |(ty, _)| match ty {
91                            LitIntType::U8 => "u8",
92                            LitIntType::U16 => "u16",
93                            LitIntType::U32 => "u32",
94                            LitIntType::U64 => "u64",
95                            LitIntType::U256 => "u256",
96                            LitIntType::I8 => "i8",
97                            LitIntType::I16 => "i16",
98                            LitIntType::I32 => "i32",
99                            LitIntType::I64 => "i64",
100                        })
101                }
102            }
103            Bool(_) => "bool",
104        }
105    }
106}
107
108impl Spanned for LitString {
109    fn span(&self) -> Span {
110        self.span.clone()
111    }
112}
113
114impl Spanned for LitChar {
115    fn span(&self) -> Span {
116        self.span.clone()
117    }
118}
119
120impl Spanned for LitInt {
121    fn span(&self) -> Span {
122        match &self.ty_opt {
123            Some((_lit_int_ty, span)) => Span::join(self.span.clone(), span),
124            None => self.span.clone(),
125        }
126    }
127}
128
129impl Spanned for LitBool {
130    fn span(&self) -> Span {
131        self.span.clone()
132    }
133}
134
135impl Spanned for Literal {
136    fn span(&self) -> Span {
137        match self {
138            Literal::String(lit_string) => lit_string.span(),
139            Literal::Char(lit_char) => lit_char.span(),
140            Literal::Int(lit_int) => lit_int.span(),
141            Literal::Bool(lit_bool) => lit_bool.span(),
142        }
143    }
144}