1use crate::lex::Cursor;
2use crate::lit::Lit;
3use crate::{Ident, LexError, Scan, Span, Spanner};
4
5#[derive(Debug, Clone)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(into = "String"))]
8pub struct LitBool {
9 value: bool,
10 span: Span,
11}
12
13impl LitBool {
14 #[inline]
15 pub fn new(value: bool, span: Span) -> Self {
16 Self { value, span }
17 }
18
19 #[inline]
20 pub fn value(&self) -> bool {
21 self.value
22 }
23
24 #[inline]
25 pub fn repr(&self) -> &str {
26 if self.value { "true" } else { "false" }
27 }
28
29 #[inline]
30 pub fn span(&self) -> Span {
31 self.span
32 }
33
34 #[inline]
35 pub fn set_span(&mut self, span: Span) {
36 self.span = span;
37 }
38}
39
40impl PartialEq for LitBool {
41 fn eq(&self, other: &Self) -> bool {
42 self.value == other.value
43 }
44}
45
46impl Eq for LitBool {}
47
48impl std::hash::Hash for LitBool {
49 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
50 self.value.hash(state);
51 }
52}
53
54impl std::fmt::Display for LitBool {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 f.write_str(self.repr())
57 }
58}
59
60impl Spanner for LitBool {
61 fn span(&self) -> Span {
62 self.span
63 }
64}
65
66impl From<LitBool> for Lit {
67 fn from(value: LitBool) -> Self {
68 Self::Bool(value)
69 }
70}
71
72impl Scan for LitBool {
73 fn scan(cursor: Cursor<'_>) -> Result<(Cursor<'_>, Self), LexError> {
74 let (cursor, ident) = Ident::scan(cursor)?;
75
76 if !ident.is_raw() && (ident.text() == "true" || ident.text() == "false") {
77 Ok((cursor, Self::new(ident.text() == "true", ident.span())))
78 } else {
79 cursor.error().message("expected bool literal").into()
80 }
81 }
82}
83
84#[cfg(feature = "serde")]
85impl From<LitBool> for String {
86 fn from(value: LitBool) -> Self {
87 value.repr().to_string()
88 }
89}