1use crate::{Cursor, CursorSink, Parse, Parser, Peek, SemanticEq, ToCursors};
2use bumpalo::Bump;
3use css_lexer::{KindSet, Span, ToSpan};
4use std::fmt;
5use std::hash::{Hash, Hasher};
6use std::ops::{Deref, DerefMut};
7
8pub struct BumpBox<'a, T> {
17 bump: &'a Bump,
18 ptr: &'a mut T,
19}
20
21impl<'a, T> BumpBox<'a, T> {
22 #[inline]
24 pub fn new_in(bump: &'a Bump, value: T) -> Self {
25 Self { bump, ptr: bump.alloc(value) }
26 }
27}
28
29impl<T> Deref for BumpBox<'_, T> {
30 type Target = T;
31
32 #[inline]
33 fn deref(&self) -> &T {
34 self.ptr
35 }
36}
37
38impl<T> DerefMut for BumpBox<'_, T> {
39 #[inline]
40 fn deref_mut(&mut self) -> &mut T {
41 self.ptr
42 }
43}
44
45impl<T: Clone> Clone for BumpBox<'_, T> {
46 fn clone(&self) -> Self {
47 let cloned = self.ptr.clone();
48 Self { bump: self.bump, ptr: self.bump.alloc(cloned) }
49 }
50}
51
52impl<T: fmt::Debug> fmt::Debug for BumpBox<'_, T> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 fmt::Debug::fmt(&**self, f)
55 }
56}
57
58impl<T: PartialEq> PartialEq for BumpBox<'_, T> {
59 fn eq(&self, other: &Self) -> bool {
60 (**self).eq(&**other)
61 }
62}
63
64impl<T: Eq> Eq for BumpBox<'_, T> {}
65
66impl<T: PartialOrd> PartialOrd for BumpBox<'_, T> {
67 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
68 (**self).partial_cmp(&**other)
69 }
70}
71
72impl<T: Ord> Ord for BumpBox<'_, T> {
73 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
74 (**self).cmp(&**other)
75 }
76}
77
78impl<T: Hash> Hash for BumpBox<'_, T> {
79 fn hash<H: Hasher>(&self, state: &mut H) {
80 (**self).hash(state)
81 }
82}
83
84impl<T: ToCursors> ToCursors for BumpBox<'_, T> {
85 fn to_cursors(&self, s: &mut impl CursorSink) {
86 (**self).to_cursors(s);
87 }
88}
89
90impl<T: SemanticEq> SemanticEq for BumpBox<'_, T> {
91 fn semantic_eq(&self, other: &Self) -> bool {
92 (**self).semantic_eq(other)
93 }
94}
95
96impl<T: ToSpan> ToSpan for BumpBox<'_, T> {
97 fn to_span(&self) -> Span {
98 (**self).to_span()
99 }
100}
101
102impl<M: crate::NodeMetadata, T: crate::NodeWithMetadata<M>> crate::NodeWithMetadata<M> for BumpBox<'_, T> {
103 fn self_metadata(&self) -> M {
104 (**self).self_metadata()
105 }
106
107 fn metadata(&self) -> M {
108 (**self).metadata()
109 }
110}
111
112impl<'a, T: Peek<'a>> Peek<'a> for BumpBox<'a, T> {
113 const PEEK_KINDSET: KindSet = T::PEEK_KINDSET;
114
115 fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
116 where
117 I: Iterator<Item = Cursor> + Clone,
118 {
119 T::peek(p, c)
120 }
121}
122
123impl<'a, T: Parse<'a>> Parse<'a> for BumpBox<'a, T> {
124 fn parse<I>(p: &mut Parser<'a, I>) -> crate::Result<Self>
125 where
126 I: Iterator<Item = Cursor> + Clone,
127 {
128 let value = T::parse(p)?;
129 Ok(BumpBox::new_in(p.bump(), value))
130 }
131}
132
133#[cfg(feature = "serde")]
134impl<T: serde::Serialize> serde::Serialize for BumpBox<'_, T> {
135 fn serialize<S: serde::Serializer>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> {
136 (**self).serialize(serializer)
137 }
138}