1use crate::extra::{SparseValueId, SparseValueMap};
6use core::any::Any;
7use fixed32::Fp;
8use seq_map::SeqMap;
9use std::cell::Ref;
10use std::cell::RefCell;
11use std::fmt::{Debug, Display};
12use std::hash::Hash;
13use std::rc::Rc;
14use swamp_script_semantic::{
15 ExternalFunctionId, ResolvedArrayTypeRef, ResolvedEnumVariantStructTypeRef,
16 ResolvedEnumVariantTupleTypeRef, ResolvedEnumVariantTypeRef, ResolvedFormatSpecifierKind,
17 ResolvedInternalFunctionDefinitionRef, ResolvedMapTypeRef, ResolvedPrecisionType,
18 ResolvedRustTypeRef, ResolvedStructTypeRef, ResolvedTupleTypeRef, TypeNumber,
19};
20use swamp_script_semantic::{ResolvedNode, Span};
21
22pub type ValueRef = Rc<RefCell<Value>>;
23
24pub trait RustType: Any + Debug + Display + QuickSerialize {
25 fn as_any(&self) -> &dyn Any;
26 fn as_any_mut(&mut self) -> &mut dyn Any;
27 fn eq_dyn(&self, other: &dyn RustType) -> bool;
28}
29
30impl<T: Any + Debug + Display + QuickSerialize + PartialEq> RustType for T {
32 fn as_any(&self) -> &dyn Any {
33 self
34 }
35
36 fn as_any_mut(&mut self) -> &mut dyn Any {
37 self
38 }
39
40 fn eq_dyn(&self, other: &dyn RustType) -> bool {
41 other
43 .as_any()
44 .downcast_ref::<T>()
45 .map_or(false, |other_t| self == other_t)
46 }
47}
48
49pub trait QuickSerialize {
50 fn quick_serialize(&self, _octets: &mut [u8]) -> usize {
51 0
52 }
53}
54
55pub trait QuickDeserialize {
56 fn quick_deserialize(octets: &[u8]) -> (Self, usize)
57 where
58 Self: Sized;
59}
60
61impl<'a, T: QuickSerialize + ?Sized> QuickSerialize for Ref<'a, T> {
62 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
63 (**self).quick_serialize(octets)
64 }
65}
66
67impl<T: QuickSerialize> QuickSerialize for Box<T> {
68 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
69 (**self).quick_serialize(octets)
71 }
72}
73
74impl QuickSerialize for Rc<RefCell<dyn RustType>> {
75 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
76 self.borrow().quick_serialize(octets)
77 }
78}
79
80#[derive(Debug, Default)]
81pub enum Value {
82 Int(i32),
83 Float(Fp),
84 String(String),
85 Bool(bool),
86 #[default]
87 Unit, Option(Option<ValueRef>),
90
91 Array(ResolvedArrayTypeRef, Vec<ValueRef>),
93 Map(ResolvedMapTypeRef, SeqMap<Value, ValueRef>), Tuple(ResolvedTupleTypeRef, Vec<ValueRef>),
95 Struct(ResolvedStructTypeRef, Vec<ValueRef>), EnumVariantSimple(ResolvedEnumVariantTypeRef),
98 EnumVariantTuple(ResolvedEnumVariantTupleTypeRef, Vec<Value>),
99 EnumVariantStruct(ResolvedEnumVariantStructTypeRef, Vec<Value>),
100
101 ExclusiveRange(Box<i32>, Box<i32>),
103 InclusiveRange(Box<i32>, Box<i32>),
104
105 InternalFunction(ResolvedInternalFunctionDefinitionRef),
107 ExternalFunction(ExternalFunctionId),
108
109 RustValue(ResolvedRustTypeRef, Rc<RefCell<Box<dyn RustType>>>),
111}
112
113#[allow(unused)]
114fn quick_serialize_values(values: &[Value], buffer: &mut [u8], depth: usize) -> usize {
115 let mut offset = 0;
116
117 for value in values {
118 let bytes_written = value.quick_serialize(&mut buffer[offset..], depth + 1);
119 offset += bytes_written;
120 }
121
122 offset
123}
124
125impl Value {
126 #[allow(clippy::too_many_lines)]
130 #[inline]
131 pub fn quick_serialize(&self, octets: &mut [u8], depth: usize) -> usize {
132 match self {
133 Self::Int(x) => {
134 let value_octets = x.to_le_bytes();
135 octets[..value_octets.len()].copy_from_slice(&value_octets);
136 value_octets.len()
137 }
138 Self::Float(fp) => {
139 let value_octets = fp.inner().to_le_bytes();
140 octets[..value_octets.len()].copy_from_slice(&value_octets);
141 value_octets.len()
142 }
143 Self::String(s) => {
144 let len = s.len() as u16;
145 let len_bytes = len.to_le_bytes();
146 octets[..len_bytes.len()].copy_from_slice(&len_bytes);
147 let mut offset = len_bytes.len();
148
149 octets[offset..offset + len as usize].copy_from_slice(s.as_bytes());
151 offset += len as usize;
152 offset
153 }
154
155 Self::Bool(b) => {
156 octets[0] = u8::from(*b);
157 1
158 }
159
160 Self::Unit => 0,
161 Self::Option(maybe_value) => match maybe_value {
162 None => {
163 octets[0] = 0;
164 1
165 }
166 Some(inner_value) => {
167 octets[0] = 1;
168 let inner_size = inner_value
169 .borrow()
170 .quick_serialize(&mut octets[1..], depth + 1);
171 1 + inner_size
172 }
173 },
174 Self::Array(_array_ref, values) => {
175 let mut offset = 0;
176
177 let count: u16 = values.len() as u16;
178 let count_octets = count.to_le_bytes();
179 octets[offset..offset + 2].copy_from_slice(&count_octets);
180 offset += count_octets.len();
181
182 for value in values {
183 let size = value
184 .borrow()
185 .quick_serialize(&mut octets[offset..], depth + 1);
186
187 offset += size;
188 }
189 offset
190 }
191 Self::Map(_map_ref, values) => {
192 let mut offset = 0;
193
194 let count: u16 = values.len() as u16;
195 let count_octets = count.to_le_bytes();
196 octets[offset..offset + count_octets.len()].copy_from_slice(&count_octets);
197 offset += count_octets.len();
198
199 for (key, value_ref) in values {
200 offset += key.quick_serialize(&mut octets[offset..], depth + 1);
201
202 let value_val = value_ref.borrow();
203 offset += value_val.quick_serialize(&mut octets[offset..], depth + 1);
204 }
205
206 offset
207 }
208
209 Self::Tuple(_tuple_type_ref, values) => {
210 let mut offset = 0;
211 for value in values {
212 let size = value
213 .borrow()
214 .quick_serialize(&mut octets[offset..], depth + 1);
215 offset += size;
216 }
217 offset
218 }
219
220 Self::Struct(_struct_type, values) => {
221 let mut offset = 0;
222 for value in values {
223 let size = value
224 .borrow()
225 .quick_serialize(&mut octets[offset..], depth + 1);
226 offset += size;
227 }
228 offset
229 }
230
231 Self::EnumVariantSimple(enum_variant) => {
232 octets[0] = enum_variant.container_index;
233 1
234 }
235 Self::EnumVariantTuple(enum_tuple_ref, values) => {
236 let mut offset = 0;
237 octets[offset] = enum_tuple_ref.common.container_index;
238 offset += 1;
239 for value in values {
240 let size = value.quick_serialize(&mut octets[offset..], depth + 1);
241 offset += size;
242 }
243 offset
244 }
245 Self::EnumVariantStruct(enum_struct_ref, values) => {
246 let mut offset = 0;
247 octets[offset] = enum_struct_ref.common.container_index;
248 offset += 1;
249 for value in values {
250 let size = value.quick_serialize(&mut octets[offset..], depth + 1);
251 offset += size;
252 }
253 offset
254 }
255
256 Self::ExclusiveRange(_, _) => {
257 todo!("range is not supported yet")
258 }
259 Self::InclusiveRange(_, _) => {
260 todo!("range is not supported yet")
261 }
262
263 Self::InternalFunction(_) => {
264 todo!("internal_functions are not supported yet")
265 }
266 Self::ExternalFunction(_) => {
267 todo!("external_functions are not supported yet")
268 }
269
270 Self::RustValue(_rust_value, rust_value) => rust_value.borrow().quick_serialize(octets),
271 }
272 }
273}
274
275impl Clone for Value {
276 fn clone(&self) -> Self {
277 match self {
278 Self::Int(i) => Self::Int(*i),
279 Self::Float(f) => Self::Float(*f),
280 Self::String(s) => Self::String(s.clone()),
281 Self::Bool(b) => Self::Bool(*b),
282 Self::Unit => Self::Unit,
283
284 Self::Option(opt) => {
285 let cloned_opt = opt.as_ref().map(std::clone::Clone::clone);
286 Self::Option(cloned_opt)
287 }
288
289 Self::Array(resolved_ref, vec_refs) => {
291 Self::Array(resolved_ref.clone(), deep_clone_valrefs(vec_refs))
292 }
293
294 Self::Map(resolved_ref, seq_map) => {
295 let cloned_seq_map = seq_map
296 .iter()
297 .map(|(key, val_ref)| (key.clone(), deep_clone_valref(val_ref)))
298 .collect();
299
300 Self::Map(resolved_ref.clone(), cloned_seq_map)
301 }
302
303 Self::Tuple(resolved_ref, vec_refs) => {
304 Self::Tuple(resolved_ref.clone(), deep_clone_valrefs(vec_refs))
305 }
306
307 Self::Struct(resolved_ref, vec_refs) => {
308 Self::Struct(resolved_ref.clone(), deep_clone_valrefs(vec_refs))
309 }
310
311 Self::EnumVariantSimple(resolved_ref) => Self::EnumVariantSimple(resolved_ref.clone()),
312
313 Self::EnumVariantTuple(resolved_ref, vec_values) => {
314 Self::EnumVariantTuple(resolved_ref.clone(), vec_values.clone())
315 }
316
317 Self::EnumVariantStruct(resolved_ref, vec_values) => {
318 Self::EnumVariantStruct(resolved_ref.clone(), vec_values.clone())
319 }
320
321 Self::ExclusiveRange(start, end) => {
322 Self::ExclusiveRange(Box::new(**start), Box::new(**end))
323 }
324
325 Self::InclusiveRange(start, end) => {
326 Self::InclusiveRange(Box::new(**start), Box::new(**end))
327 }
328
329 Self::InternalFunction(resolved_def_ref) => {
330 Self::InternalFunction(resolved_def_ref.clone())
331 }
332
333 Self::ExternalFunction(external_id) => Self::ExternalFunction(*external_id),
334
335 Self::RustValue(resolved_rust_ref, rust_type_rc) => {
336 Self::RustValue(resolved_rust_ref.clone(), rust_type_rc.clone())
337 }
338 }
339 }
340}
341
342#[inline]
343fn deep_clone_valrefs(vec_values: &[ValueRef]) -> Vec<ValueRef> {
344 vec_values.iter().map(deep_clone_valref).collect()
345}
346
347#[inline]
348fn deep_clone_valref(val_ref: &ValueRef) -> ValueRef {
349 let cloned_value = val_ref.borrow().clone();
350 Rc::new(RefCell::new(cloned_value))
351}
352
353pub fn to_rust_value<T: RustType + 'static>(type_ref: ResolvedRustTypeRef, value: T) -> Value {
354 Value::RustValue(
355 type_ref,
356 Rc::new(RefCell::new(Box::new(value) as Box<dyn RustType>)),
357 )
358}
359
360#[derive(Debug, PartialEq, Eq)]
361pub enum ValueError {
362 NotAnIterator,
363 NotSparseMap,
364 CanNotCoerceToIterator,
365 ConversionError(String),
366 WrongNumberOfArguments { expected: usize, got: usize },
367 TypeError(String),
368}
369
370pub const SPARSE_TYPE_ID: TypeNumber = 999;
371pub const SPARSE_ID_TYPE_ID: TypeNumber = 998;
372
373impl Value {
376 #[allow(clippy::should_implement_trait)] pub fn into_iter(self) -> Result<Box<dyn Iterator<Item = Self>>, ValueError> {
382 match self {
383 Self::Array(_, values) => Ok(Box::new(
385 values.into_iter().map(|item| item.borrow().clone()),
386 )),
387 Self::String(values) => Ok(Box::new(
388 values
389 .chars()
390 .map(|item| Self::String(item.to_string()))
391 .collect::<Vec<Self>>()
392 .into_iter(),
393 )),
394 Self::Map(_, seq_map) => Ok(Box::new(
395 seq_map.into_values().map(|item| item.borrow().clone()),
396 )),
397 Self::RustValue(ref rust_type_ref, _) => match rust_type_ref.number {
398 SPARSE_TYPE_ID => {
399 let sparse_map = self
400 .downcast_rust::<SparseValueMap>()
401 .expect("must be sparsemap");
402 let values: Vec<_> = sparse_map
403 .borrow()
404 .values()
405 .iter()
406 .map(|item| item.borrow().clone())
407 .collect();
408 Ok(Box::new(values.into_iter()))
409 }
410 _ => Err(ValueError::NotSparseMap),
411 },
412 Self::ExclusiveRange(start_val, max_val) => {
413 let start = *start_val;
414 let end = *max_val;
415 Ok(Box::new((start..end).map(Value::Int)))
416 }
417 Self::InclusiveRange(start_val, max_val) => {
418 let start = *start_val;
419 let end = *max_val;
420 Ok(Box::new((start..=end).map(Value::Int)))
421 }
422 _ => Err(ValueError::CanNotCoerceToIterator),
423 }
424 }
425
426 pub fn into_iter_pairs(self) -> Result<Box<dyn Iterator<Item = (Self, Self)>>, ValueError> {
431 let values = match self {
432 Self::Map(_, seq_map) => {
433 Box::new(seq_map.into_iter().map(|(k, v)| (k, v.borrow().clone())))
434 }
435 Self::Tuple(_type_ref, elements) => {
436 let iter = elements
437 .into_iter()
438 .enumerate()
439 .map(move |(i, v)| (Self::Int(i as i32), v.borrow().clone()));
440 Box::new(iter) as Box<dyn Iterator<Item = (Self, Self)>>
441 }
442 Self::Array(_type_ref, array) => {
443 let iter = array
444 .into_iter()
445 .enumerate()
446 .map(move |(i, v)| (Self::Int(i as i32), v.borrow().clone()));
447 Box::new(iter) as Box<dyn Iterator<Item = (Self, Self)>>
448 }
449 Self::String(string) => {
450 let iter = string
451 .chars()
452 .enumerate()
453 .map(|(i, v)| (Self::Int(i as i32), Self::String(v.to_string())))
454 .collect::<Vec<(Self, Self)>>()
455 .into_iter();
456 Box::new(iter) as Box<dyn Iterator<Item = (Self, Self)> + 'static>
457 }
458 Self::RustValue(ref rust_type_ref, ref _rust_value) => {
459 Box::new(match rust_type_ref.number {
460 SPARSE_TYPE_ID => {
461 let sparse_map = self
462 .downcast_rust::<SparseValueMap>()
463 .expect("must be sparsemap");
464
465 let id_type_ref = sparse_map.borrow().rust_type_ref_for_id.clone();
466
467 let pairs: Vec<_> = sparse_map
468 .borrow()
469 .iter()
470 .map(|(k, v)| {
471 (
472 Self::RustValue(
473 id_type_ref.clone(),
474 Rc::new(RefCell::new(Box::new(SparseValueId(k)))),
475 ),
476 v.borrow().clone(),
477 )
478 })
479 .collect();
480
481 Box::new(pairs.into_iter()) as Box<dyn Iterator<Item = (Self, Self)>>
482 }
483
484 _ => return Err(ValueError::NotSparseMap),
485 })
486 }
487 _ => return Err(ValueError::NotAnIterator),
488 };
489
490 Ok(values)
491 }
492
493 #[must_use]
494 pub fn convert_to_string_if_needed(&self) -> String {
495 match self {
496 Self::String(string) => string.clone(),
497 _ => self.to_string(),
498 }
499 }
500
501 pub fn expect_string(&self) -> Result<String, ValueError> {
504 match self {
505 Self::String(s) => Ok(s.clone()),
506 _ => Err(ValueError::ConversionError("Expected string value".into())),
507 }
508 }
509
510 pub fn expect_int(&self) -> Result<i32, ValueError> {
513 match self {
514 Self::Int(v) => Ok(*v),
515 _ => Err(ValueError::ConversionError("Expected int value".into())),
516 }
517 }
518
519 pub fn expect_float(&self) -> Result<Fp, ValueError> {
522 match self {
523 Self::Float(v) => Ok(*v),
524 _ => Err(ValueError::ConversionError("Expected float value".into())),
525 }
526 }
527
528 pub fn as_bool(&self) -> Result<bool, ValueError> {
531 match self {
532 Self::Bool(b) => Ok(*b),
533 _ => Err(ValueError::ConversionError("Expected bool value".into())),
534 }
535 }
536
537 pub fn is_truthy(&self) -> Result<bool, ValueError> {
540 let v = match self {
541 Self::Bool(b) => *b,
542 _ => return Err(ValueError::ConversionError("Expected bool value".into())),
543 };
544
545 Ok(v)
546 }
547
548 #[must_use]
551 pub fn downcast_rust<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
552 match self {
553 Self::RustValue(_rust_type_ref, rc) => {
554 let type_matches = {
555 let guard = rc.borrow();
556 (**guard).as_any().is::<T>()
557 };
558
559 if type_matches {
560 Some(unsafe { std::mem::transmute(rc.clone()) })
561 } else {
562 None
563 }
564 }
565 _ => None,
566 }
567 }
568
569 #[must_use]
570 pub fn downcast_hidden_rust<T: RustType + 'static>(&self) -> Option<Rc<RefCell<Box<T>>>> {
571 match self {
572 Self::Struct(_struct_ref, fields) => fields[0].borrow().downcast_rust(),
573 _ => None,
574 }
575 }
576
577 pub fn new_rust_value<T: RustType + 'static + PartialEq>(
578 rust_type_ref: ResolvedRustTypeRef,
579 value: T,
580 ) -> Self {
581 let boxed = Box::new(Box::new(value)) as Box<dyn RustType>;
582 Self::RustValue(rust_type_ref, Rc::new(RefCell::new(boxed)))
583 }
584
585 pub fn new_hidden_rust_struct<T: RustType + 'static + PartialEq>(
586 struct_type: ResolvedStructTypeRef,
587 rust_description: ResolvedRustTypeRef,
588 value: T,
589 ) -> Self {
590 let rust_value = Rc::new(RefCell::new(Self::new_rust_value(rust_description, value)));
591 Self::Struct(struct_type, vec![rust_value])
592 }
593}
594
595pub trait SourceMapLookup: Debug {
596 fn get_text(&self, resolved_node: &ResolvedNode) -> &str;
597 fn get_text_span(&self, span: &Span) -> &str;
598}
599
600impl Display for Value {
601 #[allow(clippy::too_many_lines)]
602 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
603 match self {
604 Self::Int(n) => write!(f, "{n}"),
605 Self::Float(n) => write!(f, "{n}"),
606 Self::String(s) => write!(f, "\"{s}\""),
607 Self::Bool(b) => write!(f, "{b}"),
608 Self::Array(_item_type, arr) => {
609 write!(f, "[")?;
610 for (i, val) in arr.iter().enumerate() {
611 if i > 0 {
612 write!(f, ", ")?;
613 }
614 write!(f, "{}", val.borrow())?;
615 }
616 write!(f, "]")
617 }
618 Self::Map(_map_type_ref, items) => {
619 write!(f, "[")?;
620 for (i, (key, val)) in items.iter().enumerate() {
621 if i > 0 {
622 write!(f, ", ")?;
623 }
624 write!(f, "{key}: {}", val.borrow())?;
625 }
626 write!(f, "]")
627 }
628
629 Self::Tuple(_tuple_type, arr) => {
630 write!(f, "(")?;
631 for (i, val) in arr.iter().enumerate() {
632 if i > 0 {
633 write!(f, ", ")?;
634 }
635 write!(f, "{}", val.borrow())?;
636 }
637 write!(f, ")")
638 }
639 Self::Struct(struct_type_ref, fields_in_strict_order) => {
640 write!(f, "{} {{ ", struct_type_ref.borrow().assigned_name)?;
641
642 let fields = struct_type_ref
643 .borrow()
644 .anon_struct_type
645 .defined_fields
646 .keys()
647 .cloned()
648 .collect::<Vec<_>>();
649 for (i, val) in fields_in_strict_order.iter().enumerate() {
650 if i > 0 {
651 write!(f, ", ")?;
652 }
653 let field_name = &fields[i];
654 write!(f, "{field_name}: {}", val.borrow())?;
655 }
656 write!(f, " }}")
657 }
658 Self::InternalFunction(_reference) => write!(f, "<function>"), Self::Unit => write!(f, "()"),
660 Self::ExclusiveRange(start, end) => write!(f, "{start}..{end}"),
661 Self::InclusiveRange(start, end) => write!(f, "{start}..={end}"),
662
663 Self::ExternalFunction(_) => write!(f, "<external>"), Self::EnumVariantTuple(enum_name, fields_in_order) => {
667 if enum_name.common.module_path.0.is_empty() {
668 write!(
669 f,
670 "{:?}::{:?}",
671 enum_name.common.enum_ref.borrow().name,
672 enum_name.common.variant_name,
673 )?;
674 } else {
675 write!(
676 f,
677 "{:?}::{:?}::{:?}",
678 enum_name.common.module_path,
679 enum_name.common.enum_ref.borrow().name,
680 enum_name.common.variant_name,
681 )?;
682 }
683
684 for field in fields_in_order {
685 write!(f, "{field}")?;
686 }
687
688 Ok(())
689 }
690 Self::EnumVariantStruct(struct_variant, values) => {
691 let decorated_values: Vec<(String, Value)> = struct_variant
692 .anon_struct
693 .defined_fields
694 .keys()
695 .cloned()
696 .zip(values.clone())
697 .collect();
698
699 write!(
700 f,
701 "{}::{} {{ ",
702 struct_variant.common.enum_ref.borrow().assigned_name,
703 &struct_variant.common.assigned_name
704 )?;
705
706 for (field_name, value) in &decorated_values {
707 write!(f, "{field_name}: {value}")?;
708 }
709
710 write!(f, " }}")?;
711 Ok(())
712 }
713 Self::EnumVariantSimple(enum_variant_type_ref) => write!(
714 f,
715 "{}::{}",
716 &enum_variant_type_ref.owner.borrow().assigned_name,
717 &enum_variant_type_ref.assigned_name,
718 ),
719 Self::RustValue(_rust_type, rust_type_pointer) => {
720 write!(f, "{}", rust_type_pointer.borrow())
721 }
722 Self::Option(maybe_val) => {
723 let inner_str = if maybe_val.is_none() {
724 "none"
725 } else {
726 &*maybe_val.as_ref().unwrap().borrow().to_string()
727 };
728 write!(f, "Option({inner_str})")
729 } }
731 }
732}
733
734impl PartialEq for Value {
735 fn eq(&self, other: &Self) -> bool {
736 match (self, other) {
737 (Self::Int(a), Self::Int(b)) => a == b,
739 (Self::Float(a), Self::Float(b)) => a == b,
740 (Self::String(a), Self::String(b)) => a == b,
741 (Self::Bool(a), Self::Bool(b)) => a == b,
742 (Self::Unit, Self::Unit) => true,
743 (Self::Option(r1), Self::Option(r2)) => r1 == r2,
744 _ => false,
745 }
746 }
747}
748
749impl Eq for Value {}
750
751impl Hash for Value {
752 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
753 match self {
754 Self::Int(n) => n.hash(state),
755 Self::Float(f) => f.hash(state),
756 Self::String(s) => s.hash(state),
757 Self::Bool(b) => b.hash(state),
758 Self::Unit => (),
759 Self::Option(_wrapped) => {}
760 Self::Array(_, _arr) => {}
761 Self::Struct(type_ref, values) => {
762 type_ref.borrow().name().span.hash(state);
763 for v in values {
764 v.borrow().hash(state);
765 }
766 }
767 Self::Map(_, _items) => {}
768 Self::Tuple(_, _arr) => {}
769 Self::EnumVariantSimple(_) => (),
770 Self::EnumVariantTuple(_, fields) => fields.hash(state),
771 Self::EnumVariantStruct(_, fields) => fields.hash(state),
772 Self::ExclusiveRange(start, end) => {
773 start.hash(state);
774 end.hash(state);
775 }
776 Self::InclusiveRange(start, end) => {
777 start.hash(state);
778 end.hash(state);
779 }
780 Self::RustValue(_rust_type, _rust_val) => (),
781 Self::InternalFunction(_) => (),
782 Self::ExternalFunction(_) => (),
783 }
784 }
785}
786
787pub fn format_value(value: &Value, spec: &ResolvedFormatSpecifierKind) -> Result<String, String> {
790 match (value, spec) {
791 (Value::Int(n), ResolvedFormatSpecifierKind::LowerHex) => Ok(format!("{n:x}")),
792 (Value::Int(n), ResolvedFormatSpecifierKind::UpperHex) => Ok(format!("{n:X}")),
793 (Value::Int(n), ResolvedFormatSpecifierKind::Binary) => Ok(format!("{n:b}")),
794
795 (Value::Float(f), ResolvedFormatSpecifierKind::Float) => Ok(format!("{f}")),
796 (
797 Value::Float(f),
798 ResolvedFormatSpecifierKind::Precision(prec, _node, ResolvedPrecisionType::Float),
799 ) => Ok(format!("{:.*}", *prec as usize, f)),
800
801 (
802 Value::String(s),
803 ResolvedFormatSpecifierKind::Precision(prec, _node, ResolvedPrecisionType::String, ..),
804 ) => Ok(format!("{:.*}", *prec as usize, s)),
805
806 _ => Err(format!(
807 "Unsupported format specifier {spec:?} for value type {value:?}"
808 )),
809 }
810}
811
812#[must_use]
813pub fn convert_vec_to_rc_refcell(vec: Vec<Value>) -> Vec<Rc<RefCell<Value>>> {
814 vec.into_iter().map(|v| Rc::new(RefCell::new(v))).collect()
815}