1use core::fmt;
14use core::mem::take;
15use core::ops::{Deref, DerefMut};
16
17#[cfg(feature = "musli")]
18use musli_core::{Decode, Encode};
19#[cfg(feature = "serde")]
20use serde::{Deserialize, Serialize};
21
22use crate::alloc::prelude::*;
23use crate::alloc::{self, Box, Vec};
24use crate::runtime::{AnyTypeInfo, Bytes, Inline, Object, OwnedTuple, TypeInfo, Value};
25use crate::{self as rune};
26use crate::{Hash, TypeHash};
27
28use super::{MAX_CONST_DEPTH, MAX_CONST_SIZE};
29
30#[derive(Debug, TryClone)]
40pub(crate) struct ConstNode {
41 #[try_clone(copy)]
42 pub(crate) size: u32,
43 #[try_clone(copy)]
49 pub(crate) height: u32,
50 pub(crate) kind: ConstNodeKind,
51}
52
53#[derive(Debug, TryClone)]
58#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
59#[cfg_attr(feature = "musli", derive(Decode, Encode), musli(crate = musli_core))]
60pub(crate) enum ConstNodeKind {
61 Inline(#[try_clone(copy)] Inline),
63 String(Box<str>),
65 Bytes(Box<[u8]>),
67 Instance {
70 #[try_clone(copy)]
73 hash: Hash,
74 #[try_clone(copy)]
77 variant_hash: Hash,
78 #[try_clone(copy)]
80 fields: u32,
81 },
82 Object { keys: Box<[Box<str>]> },
88}
89
90impl ConstNodeKind {
91 #[inline]
93 pub(crate) fn children(&self) -> usize {
94 match self {
95 ConstNodeKind::Instance { fields, .. } => *fields as usize,
96 ConstNodeKind::Object { keys } => keys.len(),
97 _ => 0,
98 }
99 }
100
101 pub(crate) fn type_info(&self) -> TypeInfo {
102 fn struct_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 write!(f, "unknown constant struct")
104 }
105
106 fn variant_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 write!(f, "unknown constant variant")
108 }
109
110 match self {
111 ConstNodeKind::Inline(value) => value.type_info(),
112 ConstNodeKind::String(..) => TypeInfo::any::<crate::alloc::String>(),
113 ConstNodeKind::Bytes(..) => TypeInfo::any::<Bytes>(),
114 ConstNodeKind::Object { .. } => TypeInfo::any::<Object>(),
115 ConstNodeKind::Instance {
116 hash, variant_hash, ..
117 } => match *hash {
118 Option::<Value>::HASH => TypeInfo::any::<Option<Value>>(),
119 crate::runtime::Vec::HASH => TypeInfo::any::<crate::runtime::Vec>(),
120 OwnedTuple::HASH => TypeInfo::any::<OwnedTuple>(),
121 Object::HASH => TypeInfo::any::<Object>(),
122 hash if *variant_hash == Hash::EMPTY => {
123 TypeInfo::any_type_info(AnyTypeInfo::new(struct_name, hash))
124 }
125 hash => TypeInfo::any_type_info(AnyTypeInfo::new(variant_name, hash)),
126 },
127 }
128 }
129}
130
131#[derive(Debug)]
137pub(crate) enum ConstNodesError {
138 #[cfg(any(feature = "serde", feature = "musli"))]
140 Empty,
141 #[cfg(any(feature = "serde", feature = "musli"))]
144 Malformed,
145 TooDeep { max: usize },
147 TooLarge { max: usize },
149 Alloc(alloc::Error),
151}
152
153impl From<alloc::Error> for ConstNodesError {
154 #[inline]
155 fn from(error: alloc::Error) -> Self {
156 ConstNodesError::Alloc(error)
157 }
158}
159
160impl fmt::Display for ConstNodesError {
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 match self {
163 #[cfg(any(feature = "serde", feature = "musli"))]
164 ConstNodesError::Empty => write!(f, "Constant value is empty"),
165 #[cfg(any(feature = "serde", feature = "musli"))]
166 ConstNodesError::Malformed => {
167 write!(f, "Constant value is not a tree")
168 }
169 ConstNodesError::TooDeep { max } => {
170 write!(f, "Constant value is nested too deeply, limit is {max}")
171 }
172 ConstNodesError::TooLarge { max } => {
173 write!(
174 f,
175 "Constant value is made of too many values, limit is {max}"
176 )
177 }
178 ConstNodesError::Alloc(error) => error.fmt(f),
179 }
180 }
181}
182
183impl core::error::Error for ConstNodesError {}
184
185#[cfg(any(feature = "serde", feature = "musli"))]
194fn measure(kinds: &[ConstNodeKind]) -> Result<Vec<(u32, u32)>, ConstNodesError> {
195 let len = kinds.len();
196
197 if len == 0 {
198 return Err(ConstNodesError::Empty);
199 }
200
201 if len > MAX_CONST_SIZE {
202 return Err(ConstNodesError::TooLarge {
203 max: MAX_CONST_SIZE,
204 });
205 }
206
207 let mut sizes = Vec::new();
208 let mut heights = Vec::new();
209 sizes.try_resize(len, 0u32)?;
210 heights.try_resize(len, 0u32)?;
211
212 let mut pending = Vec::new();
216
217 for index in (0..len).rev() {
218 let mut size = 1u32;
219 let mut height = 1u32;
220
221 for _ in 0..kinds[index].children() {
222 let child: usize = pending.pop().ok_or(ConstNodesError::Malformed)?;
223
224 size = size
225 .checked_add(sizes[child])
226 .ok_or(ConstNodesError::Malformed)?;
227
228 height = height.max(heights[child].saturating_add(1));
229 }
230
231 sizes[index] = size;
232 heights[index] = height;
233 pending.try_push(index)?;
234 }
235
236 if pending.len() != 1 {
239 return Err(ConstNodesError::Malformed);
240 }
241
242 if heights[0] as usize > MAX_CONST_DEPTH {
243 return Err(ConstNodesError::TooDeep {
244 max: MAX_CONST_DEPTH,
245 });
246 }
247
248 let mut out = Vec::try_with_capacity(len)?;
249
250 for index in 0..len {
251 out.try_push((sizes[index], heights[index]))?;
252 }
253
254 Ok(out)
255}
256
257#[derive(Clone, Copy)]
262pub struct ConstFields<'a> {
263 nodes: &'a [ConstNode],
264 len: usize,
265}
266
267impl<'a> ConstFields<'a> {
268 pub(crate) const EMPTY: ConstFields<'static> = ConstFields { nodes: &[], len: 0 };
270
271 #[inline]
273 pub fn len(&self) -> usize {
274 self.len
275 }
276
277 #[inline]
279 pub fn is_empty(&self) -> bool {
280 self.len == 0
281 }
282
283 pub fn get(&self, index: usize) -> Option<&'a ConstValue> {
288 if index >= self.len {
289 return None;
290 }
291
292 let mut nodes = self.nodes;
293
294 for _ in 0..index {
295 let size = nodes.first()?.size as usize;
296 nodes = nodes.get(size..)?;
297 }
298
299 let size = nodes.first()?.size as usize;
300 Some(ConstValue::from_nodes(nodes.get(..size)?))
301 }
302
303 #[inline]
305 pub fn iter(&self) -> ConstFieldsIter<'a> {
306 ConstFieldsIter {
307 nodes: self.nodes,
308 len: self.len,
309 }
310 }
311}
312
313impl fmt::Debug for ConstFields<'_> {
314 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
315 f.debug_list().entries(self.iter()).finish()
316 }
317}
318
319impl<'a> IntoIterator for ConstFields<'a> {
320 type Item = &'a ConstValue;
321 type IntoIter = ConstFieldsIter<'a>;
322
323 #[inline]
324 fn into_iter(self) -> Self::IntoIter {
325 self.iter()
326 }
327}
328
329#[derive(Clone)]
331pub struct ConstFieldsIter<'a> {
332 nodes: &'a [ConstNode],
333 len: usize,
334}
335
336impl<'a> Iterator for ConstFieldsIter<'a> {
337 type Item = &'a ConstValue;
338
339 #[inline]
340 fn next(&mut self) -> Option<Self::Item> {
341 if self.len == 0 {
342 return None;
343 }
344
345 let size = self.nodes.first()?.size as usize;
346 let (head, tail) = self.nodes.split_at_checked(size)?;
347 self.nodes = tail;
348 self.len -= 1;
349 Some(ConstValue::from_nodes(head))
350 }
351
352 #[inline]
353 fn size_hint(&self) -> (usize, Option<usize>) {
354 (self.len, Some(self.len))
355 }
356}
357
358impl ExactSizeIterator for ConstFieldsIter<'_> {
359 #[inline]
360 fn len(&self) -> usize {
361 self.len
362 }
363}
364
365#[repr(transparent)]
375pub struct ConstValue {
376 nodes: [ConstNode],
377}
378
379impl ConstValue {
380 #[inline]
385 pub(crate) fn from_nodes(nodes: &[ConstNode]) -> &Self {
386 unsafe { &*(nodes as *const [ConstNode] as *const ConstValue) }
388 }
389
390 #[inline]
392 pub(crate) fn as_nodes(&self) -> &[ConstNode] {
393 &self.nodes
394 }
395
396 #[inline]
398 pub(crate) fn kind(&self) -> &ConstNodeKind {
399 match self.nodes.first() {
401 Some(node) => &node.kind,
402 None => &ConstNodeKind::Inline(Inline::Empty),
403 }
404 }
405
406 #[inline]
413 pub fn fields(&self) -> ConstFields<'_> {
414 let Some((_, rest)) = self.nodes.split_first() else {
415 return ConstFields::EMPTY;
416 };
417
418 ConstFields {
419 nodes: rest,
420 len: self.kind().children(),
421 }
422 }
423
424 #[inline]
429 pub(crate) fn kind_mut(&mut self) -> Option<&mut ConstNodeKind> {
430 Some(&mut self.nodes.first_mut()?.kind)
431 }
432
433 #[inline]
438 pub(crate) fn height(&self) -> u32 {
439 match self.nodes.first() {
440 Some(node) => node.height,
441 None => 0,
442 }
443 }
444
445 #[inline]
447 pub(crate) fn type_info(&self) -> TypeInfo {
448 self.kind().type_info()
449 }
450}
451
452impl fmt::Debug for ConstValue {
453 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454 self::debug::fmt(self, f)
455 }
456}
457
458impl TryToOwned for ConstValue {
459 type Owned = ConstValueBuf;
460
461 #[inline]
462 fn try_to_owned(&self) -> alloc::Result<Self::Owned> {
463 ConstValueBuf::from_vec(self.nodes.try_to_owned()?)
464 }
465}
466
467pub struct ConstValueBuf {
476 nodes: Nodes,
477}
478
479enum Nodes {
484 One(ConstNode),
485 Many(Box<[ConstNode]>),
486}
487
488impl Nodes {
489 #[inline]
490 fn as_slice(&self) -> &[ConstNode] {
491 match self {
492 Nodes::One(node) => core::slice::from_ref(node),
493 Nodes::Many(nodes) => nodes,
494 }
495 }
496
497 #[inline]
498 fn as_mut_slice(&mut self) -> &mut [ConstNode] {
499 match self {
500 Nodes::One(node) => core::slice::from_mut(node),
501 Nodes::Many(nodes) => nodes,
502 }
503 }
504}
505
506impl TryClone for Nodes {
507 #[inline]
508 fn try_clone(&self) -> alloc::Result<Self> {
509 Ok(match self {
510 Nodes::One(node) => Nodes::One(node.try_clone()?),
511 Nodes::Many(nodes) => Nodes::Many(nodes.try_clone()?),
512 })
513 }
514}
515
516impl ConstValueBuf {
517 pub(crate) fn from_vec(nodes: Vec<ConstNode>) -> alloc::Result<Self> {
519 let mut nodes = nodes;
520
521 if nodes.len() == 1 {
524 if let Some(node) = nodes.pop() {
525 return Ok(Self {
526 nodes: Nodes::One(node),
527 });
528 }
529 }
530
531 Ok(Self {
532 nodes: Nodes::Many(nodes.try_into_boxed_slice()?),
533 })
534 }
535
536 #[cfg(any(feature = "serde", feature = "musli"))]
542 pub(crate) fn from_kinds(kinds: Vec<ConstNodeKind>) -> Result<Self, ConstNodesError> {
543 let sizes = measure(&kinds)?;
544
545 let mut nodes = Vec::try_with_capacity(kinds.len())?;
546
547 for ((size, height), kind) in sizes.into_iter().zip(kinds) {
548 nodes.try_push(ConstNode { size, height, kind })?;
549 }
550
551 Ok(Self::from_vec(nodes)?)
552 }
553
554 #[cfg(any(feature = "serde", feature = "musli"))]
557 #[inline]
558 pub(crate) fn kinds(&self) -> impl ExactSizeIterator<Item = &ConstNodeKind> + '_ {
559 self.nodes.as_slice().iter().map(|node| &node.kind)
560 }
561}
562
563impl ConstValueBuf {
564 #[inline]
568 pub(crate) fn from_kind(kind: ConstNodeKind) -> Self {
569 Self {
570 nodes: Nodes::One(ConstNode {
571 size: 1,
572 height: 1,
573 kind,
574 }),
575 }
576 }
577}
578
579impl Deref for ConstValueBuf {
580 type Target = ConstValue;
581
582 #[inline]
583 fn deref(&self) -> &Self::Target {
584 ConstValue::from_nodes(self.nodes.as_slice())
585 }
586}
587
588impl DerefMut for ConstValueBuf {
589 #[inline]
590 fn deref_mut(&mut self) -> &mut Self::Target {
591 let nodes = self.nodes.as_mut_slice();
592 unsafe { &mut *(nodes as *mut [ConstNode] as *mut ConstValue) }
594 }
595}
596
597#[cfg(feature = "serde")]
601impl Serialize for ConstValueBuf {
602 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
603 where
604 S: serde::Serializer,
605 {
606 use serde::ser::SerializeSeq;
607
608 let mut seq = serializer.serialize_seq(Some(self.nodes.as_slice().len()))?;
609
610 for kind in self.kinds() {
611 seq.serialize_element(kind)?;
612 }
613
614 seq.end()
615 }
616}
617
618#[cfg(feature = "serde")]
621impl<'de> Deserialize<'de> for ConstValueBuf {
622 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
623 where
624 D: serde::Deserializer<'de>,
625 {
626 use serde::de::Error;
627
628 let kinds = Vec::<ConstNodeKind>::deserialize(deserializer)?;
629 ConstValueBuf::from_kinds(kinds).map_err(D::Error::custom)
630 }
631}
632
633#[cfg(feature = "musli")]
634impl<M> Encode<M> for ConstValueBuf
635where
636 ConstNodeKind: Encode<M>,
637{
638 type Encode = Self;
639
640 const IS_BITWISE_ENCODE: bool = false;
641
642 #[inline]
643 fn encode<E>(&self, encoder: E) -> Result<(), E::Error>
644 where
645 E: musli_core::en::Encoder<Mode = M>,
646 {
647 use musli_core::en::{Encoder, SequenceEncoder};
648
649 encoder.encode_sequence_fn(self.nodes.as_slice().len(), |seq| {
650 for kind in self.kinds() {
651 seq.encode_next()?.encode(kind)?;
652 }
653
654 Ok(())
655 })
656 }
657
658 #[inline]
659 fn as_encode(&self) -> &Self::Encode {
660 self
661 }
662}
663
664#[cfg(feature = "musli")]
665impl<'de, M, A> Decode<'de, M, A> for ConstValueBuf
666where
667 A: musli_core::Allocator,
668 ConstNodeKind: Decode<'de, M, A>,
669{
670 const IS_BITWISE_DECODE: bool = false;
671
672 #[inline]
673 fn decode<D>(decoder: D) -> Result<Self, D::Error>
674 where
675 D: musli_core::de::Decoder<'de, Mode = M, Allocator = A>,
676 {
677 use musli_core::Context;
678
679 let cx = decoder.cx();
680 let kinds = decoder.decode::<Vec<ConstNodeKind>>()?;
681 ConstValueBuf::from_kinds(kinds).map_err(|error| cx.custom(error))
682 }
683}
684
685impl AsRef<ConstValue> for ConstValueBuf {
686 #[inline]
687 fn as_ref(&self) -> &ConstValue {
688 self
689 }
690}
691
692impl core::borrow::Borrow<ConstValue> for ConstValueBuf {
693 #[inline]
694 fn borrow(&self) -> &ConstValue {
695 self
696 }
697}
698
699impl TryClone for ConstValueBuf {
700 #[inline]
701 fn try_clone(&self) -> alloc::Result<Self> {
702 Ok(Self {
703 nodes: self.nodes.try_clone()?,
704 })
705 }
706}
707
708impl fmt::Debug for ConstValueBuf {
709 #[inline]
710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
711 fmt::Debug::fmt(&**self, f)
712 }
713}
714
715pub(crate) struct ConstBuilder {
722 nodes: Vec<ConstNode>,
723 levels: Vec<u32>,
726 height: u32,
729}
730
731impl ConstBuilder {
732 #[inline]
733 pub(crate) fn new() -> Self {
734 Self {
735 nodes: Vec::new(),
736 levels: Vec::new(),
737 height: 0,
738 }
739 }
740
741 #[inline]
744 pub(crate) fn len(&self) -> usize {
745 self.nodes.len()
746 }
747
748 #[inline]
750 fn record(&mut self, height: u32) {
751 match self.levels.last_mut() {
752 Some(level) => *level = (*level).max(height),
753 None => self.height = self.height.max(height),
754 }
755 }
756
757 #[inline]
759 pub(crate) fn leaf(&mut self, kind: ConstNodeKind) -> alloc::Result<()> {
760 self.nodes.try_push(ConstNode {
761 size: 1,
762 height: 1,
763 kind,
764 })?;
765
766 self.record(1);
767 Ok(())
768 }
769
770 #[inline]
773 pub(crate) fn open(&mut self, kind: ConstNodeKind) -> alloc::Result<usize> {
774 let at = self.nodes.len();
775
776 self.nodes.try_push(ConstNode {
777 size: 0,
778 height: 0,
779 kind,
780 })?;
781
782 self.levels.try_push(0)?;
783 Ok(at)
784 }
785
786 #[inline]
788 pub(crate) fn close(&mut self, at: usize) {
789 let below = self.levels.pop().unwrap_or(0);
790 let height = below.saturating_add(1);
791 let size = self.nodes.len().saturating_sub(at);
792
793 if let Some(node) = self.nodes.get_mut(at) {
794 node.size = size as u32;
795 node.height = height;
796 }
797
798 self.record(height);
799 }
800
801 #[inline]
803 pub(crate) fn extend(&mut self, value: &ConstValue) -> alloc::Result<()> {
804 self.nodes.try_reserve(value.as_nodes().len())?;
805
806 for node in value.as_nodes() {
807 self.nodes.try_push(node.try_clone()?)?;
808 }
809
810 self.record(value.height());
811 Ok(())
812 }
813
814 pub(crate) fn build(mut self) -> Result<ConstValueBuf, ConstNodesError> {
820 if self.nodes.is_empty() {
821 self.leaf(ConstNodeKind::Inline(Inline::Empty))?;
822 }
823
824 if self.nodes.len() > MAX_CONST_SIZE {
825 return Err(ConstNodesError::TooLarge {
826 max: MAX_CONST_SIZE,
827 });
828 }
829
830 if self.height as usize > MAX_CONST_DEPTH {
831 return Err(ConstNodesError::TooDeep {
832 max: MAX_CONST_DEPTH,
833 });
834 }
835
836 Ok(ConstValueBuf::from_vec(take(&mut self.nodes))?)
837 }
838}
839
840mod debug {
842 use core::fmt;
843
844 use crate::alloc::{Box, Vec};
845 use crate::Hash;
846
847 use super::{ConstNodeKind, ConstValue};
848
849 struct Level<'a> {
851 remaining: usize,
853 total: usize,
855 keys: Option<&'a [Box<str>]>,
857 }
858
859 pub(super) fn fmt(value: &ConstValue, f: &mut fmt::Formatter<'_>) -> fmt::Result {
860 let mut levels = Vec::<Level<'_>>::new();
864
865 for node in value.as_nodes() {
866 if let Some(level) = levels.last_mut() {
867 let index = level.total - level.remaining;
868
869 if index > 0 {
870 write!(f, ", ")?;
871 }
872
873 if let Some(key) = level.keys.and_then(|keys| keys.get(index)) {
874 write!(f, "{key:?}: ")?;
875 }
876
877 level.remaining -= 1;
878 }
879
880 let level = match &node.kind {
881 ConstNodeKind::Inline(value) => {
882 write!(f, "{value:?}")?;
883 None
884 }
885 ConstNodeKind::String(value) => {
886 write!(f, "{value:?}")?;
887 None
888 }
889 ConstNodeKind::Bytes(value) => {
890 write!(f, "{value:?}")?;
891 None
892 }
893 ConstNodeKind::Instance {
894 hash,
895 variant_hash,
896 fields,
897 } => {
898 if *variant_hash == Hash::EMPTY {
899 write!(f, "{hash}(")?;
900 } else {
901 write!(f, "{hash}::{variant_hash}(")?;
902 }
903
904 Some(Level {
905 remaining: *fields as usize,
906 total: *fields as usize,
907 keys: None,
908 })
909 }
910 ConstNodeKind::Object { keys } => {
911 write!(f, "#{{")?;
912
913 Some(Level {
914 remaining: keys.len(),
915 total: keys.len(),
916 keys: Some(keys),
917 })
918 }
919 };
920
921 if let Some(level) = level {
922 levels.try_push(level).map_err(|_| fmt::Error)?;
923 }
924
925 while levels.last().is_some_and(|level| level.remaining == 0) {
928 let Some(level) = levels.pop() else {
929 break;
930 };
931
932 if level.keys.is_some() {
933 write!(f, "}}")?;
934 } else {
935 write!(f, ")")?;
936 }
937 }
938 }
939
940 Ok(())
941 }
942}