1use crate::ast::{DepthLimiter, FromTokens, ParseError, Tokens};
2use crate::lexical_token::{
3 FloatValue, IntValue, LexicalToken, Name, PunctuatorType, StringValue, Variable,
4};
5use crate::{HasSpan, Span};
6use bluejay_core::{
7 AsIter, ListValue as CoreListValue, ObjectValue as CoreObjectValue, Value as CoreValue,
8 ValueReference,
9};
10
11#[derive(Debug)]
12pub enum Value<'a, const CONST: bool> {
13 Variable(Variable<'a>),
14 Integer(IntValue),
15 Float(FloatValue),
16 String(StringValue<'a>),
17 Boolean(BooleanValue),
18 Null(Name<'a>),
19 Enum(Name<'a>),
20 List(ListValue<'a, CONST>),
21 Object(ObjectValue<'a, CONST>),
22}
23
24impl<'a, const CONST: bool> CoreValue<CONST> for Value<'a, CONST> {
25 type List = ListValue<'a, CONST>;
26 type Object = ObjectValue<'a, CONST>;
27 type Variable = Variable<'a>;
28
29 fn as_ref(&self) -> ValueReference<'_, CONST, Self> {
30 match self {
31 Self::Variable(v) => ValueReference::Variable(v),
32 Self::Integer(i) => ValueReference::Integer(i.value()),
33 Self::Float(f) => ValueReference::Float(f.value()),
34 Self::String(s) => ValueReference::String(s.as_ref()),
35 Self::Boolean(b) => ValueReference::Boolean(b.value()),
36 Self::Null(_) => ValueReference::Null,
37 Self::Enum(e) => ValueReference::Enum(e.as_ref()),
38 Self::List(l) => ValueReference::List(l),
39 Self::Object(o) => ValueReference::Object(o),
40 }
41 }
42}
43
44impl<'a, const CONST: bool> FromTokens<'a> for Value<'a, CONST> {
45 fn from_tokens(
46 tokens: &mut impl Tokens<'a>,
47 depth_limiter: DepthLimiter,
48 ) -> Result<Self, ParseError> {
49 match tokens.next() {
50 Some(LexicalToken::IntValue(int)) => Ok(Self::Integer(int)),
51 Some(LexicalToken::FloatValue(float)) => Ok(Self::Float(float)),
52 Some(LexicalToken::StringValue(string)) => Ok(Self::String(string)),
53 Some(LexicalToken::Name(name)) => Ok(match name.as_str() {
54 "true" => Self::Boolean(BooleanValue {
55 value: true,
56 span: name.into(),
57 }),
58 "false" => Self::Boolean(BooleanValue {
59 value: false,
60 span: name.into(),
61 }),
62 "null" => Self::Null(name),
63 _ => Self::Enum(name),
64 }),
65 Some(LexicalToken::VariableName(name)) => {
66 if CONST {
67 Err(ParseError::UnexpectedToken { span: name.into() })
68 } else {
69 Ok(Self::Variable(name))
70 }
71 }
72 Some(LexicalToken::Punctuator(p))
73 if p.r#type() == PunctuatorType::OpenSquareBracket =>
74 {
75 let open_span = p.span().clone();
76 let mut list: Vec<Self> = Vec::new();
77 let close_span = loop {
78 if let Some(close_span) =
79 tokens.next_if_punctuator(PunctuatorType::CloseSquareBracket)
80 {
81 break close_span;
82 }
83 list.push(Self::from_tokens(tokens, depth_limiter.bump()?)?);
84 };
85 let span = open_span.merge(&close_span);
86 Ok(Self::List(ListValue {
87 elements: list,
88 span,
89 }))
90 }
91 Some(LexicalToken::Punctuator(p)) if p.r#type() == PunctuatorType::OpenBrace => {
92 let open_span = p.span().clone();
93 let mut object: Vec<_> = Vec::new();
94 let close_span = loop {
95 if let Some(close_span) = tokens.next_if_punctuator(PunctuatorType::CloseBrace)
96 {
97 break close_span;
98 }
99 let name = tokens.expect_name()?;
100 tokens.expect_punctuator(PunctuatorType::Colon)?;
101 let value = Self::from_tokens(tokens, depth_limiter.bump()?)?;
102 object.push((name, value));
103 };
104 let span = open_span.merge(&close_span);
105 Ok(Self::Object(ObjectValue {
106 fields: object,
107 span,
108 }))
109 }
110 token => Err(token
111 .map(|token| ParseError::UnexpectedToken { span: token.into() })
112 .unwrap_or_else(|| tokens.unexpected_eof())),
113 }
114 }
115}
116
117impl<const CONST: bool> HasSpan for Value<'_, CONST> {
118 fn span(&self) -> &Span {
119 match self {
120 Self::Boolean(b) => &b.span,
121 Self::Enum(e) => e.span(),
122 Self::Float(f) => f.span(),
123 Self::Integer(i) => i.span(),
124 Self::List(l) => &l.span,
125 Self::Null(n) => n.span(),
126 Self::Object(o) => &o.span,
127 Self::String(s) => s.span(),
128 Self::Variable(v) => v.span(),
129 }
130 }
131}
132
133pub type ConstValue<'a> = Value<'a, true>;
134pub type VariableValue<'a> = Value<'a, false>;
135
136#[derive(Debug)]
137pub struct BooleanValue {
138 value: bool,
139 span: Span,
140}
141
142impl BooleanValue {
143 fn value(&self) -> bool {
144 self.value
145 }
146}
147
148#[derive(Debug)]
149pub struct ListValue<'a, const CONST: bool> {
150 elements: Vec<Value<'a, CONST>>,
151 span: Span,
152}
153
154impl<'a, const CONST: bool> CoreListValue<CONST> for ListValue<'a, CONST> {
155 type Value = Value<'a, CONST>;
156}
157
158impl<'a, const CONST: bool> AsIter for ListValue<'a, CONST> {
159 type Item = Value<'a, CONST>;
160 type Iterator<'b>
161 = std::slice::Iter<'b, Self::Item>
162 where
163 'a: 'b;
164
165 fn iter(&self) -> Self::Iterator<'_> {
166 self.elements.iter()
167 }
168}
169
170#[derive(Debug)]
171pub struct ObjectValue<'a, const CONST: bool> {
172 fields: Vec<(Name<'a>, Value<'a, CONST>)>,
173 span: Span,
174}
175
176impl<'a, const CONST: bool> CoreObjectValue<CONST> for ObjectValue<'a, CONST> {
177 type Key = Name<'a>;
178 type Value = Value<'a, CONST>;
179 type Iterator<'b>
180 = std::iter::Map<
181 std::slice::Iter<'b, (Name<'a>, Value<'a, CONST>)>,
182 fn(&'b (Name<'a>, Value<'a, CONST>)) -> (&'b Name<'a>, &'b Value<'a, CONST>),
183 >
184 where
185 'a: 'b;
186
187 fn iter(&self) -> Self::Iterator<'_> {
188 self.fields.iter().map(|(key, value)| (key, value))
189 }
190}
191
192impl<'a, const CONST: bool> AsIter for ObjectValue<'a, CONST> {
193 type Item = (Name<'a>, Value<'a, CONST>);
194 type Iterator<'b>
195 = std::slice::Iter<'b, (Name<'a>, Value<'a, CONST>)>
196 where
197 'a: 'b;
198
199 fn iter(&self) -> Self::Iterator<'_> {
200 self.fields.iter()
201 }
202}
203
204impl<const CONST: bool> HasSpan for ObjectValue<'_, CONST> {
205 fn span(&self) -> &Span {
206 &self.span
207 }
208}