Skip to main content

microcad_lang_parse/ast/
literal.rs

1// Copyright © 2026 The µcad authors <info@microcad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4use crate::ast::{ItemExtras, Span, Unit};
5
6use microcad_lang_base::CompactString;
7use std::num::{ParseFloatError, ParseIntError};
8use thiserror::Error;
9
10/// A literal value
11#[derive(Debug, PartialEq)]
12#[allow(missing_docs)]
13pub struct Literal {
14    pub span: Span,
15    pub extras: ItemExtras,
16    pub literal: LiteralKind,
17}
18
19/// The various types of literal values a [`Literal`] can contain
20#[derive(Debug, PartialEq)]
21#[allow(missing_docs)]
22pub enum LiteralKind {
23    Error(LiteralError),
24    String(StringLiteral),
25    Bool(BoolLiteral),
26    Integer(IntegerLiteral),
27    Float(FloatLiteral),
28    Quantity(QuantityLiteral),
29}
30
31impl LiteralKind {
32    /// Get the span for the literal
33    pub fn span(&self) -> Span {
34        match self {
35            LiteralKind::Error(lit) => lit.span.clone(),
36            LiteralKind::String(lit) => lit.span.clone(),
37            LiteralKind::Bool(lit) => lit.span.clone(),
38            LiteralKind::Integer(lit) => lit.span.clone(),
39            LiteralKind::Float(lit) => lit.span.clone(),
40            LiteralKind::Quantity(lit) => lit.span.clone(),
41        }
42    }
43}
44
45/// A string literal, without format expressions
46#[derive(Debug, PartialEq)]
47#[allow(missing_docs)]
48pub struct StringLiteral {
49    pub span: Span,
50    pub content: String,
51}
52
53/// A boolean literal, either `true` or `false`
54#[derive(Debug, PartialEq)]
55#[allow(missing_docs)]
56pub struct BoolLiteral {
57    pub span: Span,
58    pub value: bool,
59}
60
61/// An integer literal without type
62#[derive(Debug, PartialEq)]
63#[allow(missing_docs)]
64pub struct IntegerLiteral {
65    pub span: Span,
66    pub value: i64,
67    pub raw: CompactString,
68}
69
70/// An float literal without type
71#[derive(Debug, PartialEq)]
72#[allow(missing_docs)]
73pub struct FloatLiteral {
74    pub span: Span,
75    pub value: f64,
76    pub raw: CompactString,
77}
78
79/// A float literal with type
80#[derive(Debug, PartialEq)]
81#[allow(missing_docs)]
82pub struct QuantityLiteral {
83    pub span: Span,
84    pub value: f64,
85    pub raw: CompactString,
86    pub unit: Unit,
87}
88
89/// An error that can be encountered while parsing literal tokens
90#[derive(Debug, PartialEq, Clone)]
91#[allow(missing_docs)]
92pub struct LiteralError {
93    pub span: Span,
94    pub kind: LiteralErrorKind,
95}
96
97#[derive(Debug, Error, PartialEq, Clone)]
98#[allow(missing_docs)]
99pub enum LiteralErrorKind {
100    #[error(transparent)]
101    Float(#[from] ParseFloatError),
102    #[error(transparent)]
103    Int(#[from] ParseIntError),
104    #[error("unclosed string literal")]
105    UnclosedString,
106    #[error("only numeric literals can be typed")]
107    Untypable,
108}