1#[cfg(feature = "std")]
2use crate::queryselector::{self, QuerySelectorIterator};
3use crate::{
4 Bytes, InnerNodeHandle, ParseError,
5 inline::{hashmap::InlineHashMap, vec::InlineVec},
6};
7use core::{fmt, mem};
8#[cfg(feature = "std")]
9use std::borrow::Cow;
10
11use super::{Parser, handle::NodeHandle};
12
13const INLINED_ATTRIBUTES: usize = 8;
14const INLINED_SUBNODES: usize = 256;
15const HTML_VOID_ELEMENTS: [&str; 16] = [
16 "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link",
17 "meta", "param", "source", "track", "wbr",
18];
19
20pub type RawAttributesMap<'a> = InlineHashMap<Bytes<'a>, Option<Bytes<'a>>, INLINED_ATTRIBUTES>;
22
23pub type RawChildren = InlineVec<NodeHandle, INLINED_SUBNODES>;
25
26#[derive(Debug, Clone)]
28pub struct Attributes<'a> {
29 pub(crate) raw: RawAttributesMap<'a>,
31 pub(crate) id: Option<Bytes<'a>>,
33 pub(crate) class: Option<Bytes<'a>>,
35}
36
37impl<'a> Attributes<'a> {
38 pub(crate) fn new() -> Self {
40 Self {
41 raw: InlineHashMap::new(),
42 id: None,
43 class: None,
44 }
45 }
46
47 pub fn len(&self) -> usize {
49 let mut raw = self.raw.len();
50 if self.id.is_some() {
51 raw += 1;
52 }
53 if self.class.is_some() {
54 raw += 1;
55 }
56 raw
57 }
58
59 pub fn is_empty(&self) -> bool {
61 self.len() == 0
62 }
63
64 pub fn is_class_member<B: AsRef<[u8]>>(&self, member: B) -> bool {
66 self.class_iter()
67 .is_some_and(|mut i| i.any(|s| s.as_bytes() == member.as_ref()))
68 }
69
70 pub fn get<B>(&self, key: B) -> Option<Option<&Bytes<'a>>>
74 where
75 B: Into<Bytes<'a>>,
76 {
77 let key: Bytes = key.into();
78
79 match key.as_bytes() {
80 b"id" => self.id.as_ref().map(Some),
81 b"class" => self.class.as_ref().map(Some),
82 _ => self.raw.get(&key).map(|x| x.as_ref()),
83 }
84 }
85
86 pub fn contains<B>(&self, key: B) -> bool
88 where
89 B: Into<Bytes<'a>>,
90 {
91 self.get(key).is_some()
92 }
93
94 pub fn remove<B>(&mut self, key: B) -> Option<Option<Bytes<'a>>>
112 where
113 B: Into<Bytes<'a>>,
114 {
115 let key: Bytes = key.into();
116
117 match key.as_bytes() {
118 b"id" => self.id.take().map(Some),
119 b"class" => self.class.take().map(Some),
120 _ => self.raw.remove(&key),
121 }
122 }
123
124 pub fn remove_value<B>(&mut self, key: B) -> Option<Bytes<'a>>
139 where
140 B: Into<Bytes<'a>>,
141 {
142 let key: Bytes = key.into();
143
144 match key.as_bytes() {
145 b"id" => self.id.take(),
146 b"class" => self.class.take(),
147 _ => self.raw.get_mut(&key).and_then(mem::take),
148 }
149 }
150
151 pub fn get_mut<B>(&mut self, key: B) -> Option<Option<&mut Bytes<'a>>>
153 where
154 B: Into<Bytes<'a>>,
155 {
156 let key: Bytes = key.into();
157
158 match key.as_bytes() {
159 b"id" => self.id.as_mut().map(Some),
160 b"class" => self.class.as_mut().map(Some),
161 _ => self.raw.get_mut(&key).map(Option::as_mut),
162 }
163 }
164
165 pub fn insert<K, V>(&mut self, key: K, value: Option<V>) -> Result<(), ParseError>
167 where
168 K: Into<Bytes<'a>>,
169 V: Into<Bytes<'a>>,
170 {
171 let key: Bytes = key.into();
172 let value = value.map(Into::into);
173
174 match key.as_bytes() {
175 b"id" => self.id = value,
176 b"class" => self.class = value,
177 _ => {
178 self.raw
179 .insert(key, value)
180 .map_err(|_| ParseError::AttributeCapacityExceeded)?;
181 }
182 };
183 Ok(())
184 }
185
186 #[cfg(feature = "std")]
188 pub fn iter(&self) -> impl Iterator<Item = (Cow<'_, str>, Option<Cow<'_, str>>)> + '_ {
189 self.raw
190 .iter()
191 .map(|(k, v)| {
192 let k = k.as_utf8_str();
193 let v = v.as_ref().map(|x| x.as_utf8_str());
194
195 (Some(k), v)
196 })
197 .chain([
198 (
199 self.id.is_some().then_some(Cow::Borrowed("id")),
200 self.id.as_ref().map(|x| x.as_utf8_str()),
201 ),
202 (
203 self.class.is_some().then_some(Cow::Borrowed("class")),
204 self.class.as_ref().map(|x| x.as_utf8_str()),
205 ),
206 ])
207 .flat_map(|(k, v)| k.map(|k| (k, v)))
208 }
209
210 pub fn id(&self) -> Option<&Bytes<'a>> {
212 self.id.as_ref()
213 }
214
215 pub fn class(&self) -> Option<&Bytes<'a>> {
217 self.class.as_ref()
218 }
219
220 pub fn class_iter(&self) -> Option<impl Iterator<Item = &'_ str> + '_> {
222 self.class
223 .as_ref()
224 .and_then(Bytes::try_as_utf8_str)
225 .map(str::split_ascii_whitespace)
226 }
227
228 pub fn unstable_raw(&self) -> &RawAttributesMap<'a> {
236 &self.raw
237 }
238}
239
240#[derive(Debug, Clone)]
242pub struct HTMLTag<'a> {
243 pub(crate) _name: Bytes<'a>,
244 pub(crate) _attributes: Attributes<'a>,
245 pub(crate) _children: RawChildren,
246 pub(crate) _raw: Bytes<'a>,
247}
248
249impl<'a> HTMLTag<'a> {
250 #[inline(always)]
252 pub(crate) fn new(
253 name: Bytes<'a>,
254 attr: Attributes<'a>,
255 children: InlineVec<NodeHandle, INLINED_SUBNODES>,
256 raw: Bytes<'a>,
257 ) -> Self {
258 Self {
259 _name: name,
260 _attributes: attr,
261 _children: children,
262 _raw: raw,
263 }
264 }
265
266 #[inline]
268 pub fn children(&self) -> Children<'a, '_> {
269 Children(self)
270 }
271
272 pub fn children_mut(&mut self) -> ChildrenMut<'a, '_> {
274 ChildrenMut(self)
275 }
276
277 #[inline]
279 pub fn name(&self) -> &Bytes<'a> {
280 &self._name
281 }
282
283 #[inline]
285 pub fn name_mut(&mut self) -> &mut Bytes<'a> {
286 &mut self._name
287 }
288
289 #[inline]
291 pub fn attributes(&self) -> &Attributes<'a> {
292 &self._attributes
293 }
294
295 #[inline]
297 pub fn attributes_mut(&mut self) -> &mut Attributes<'a> {
298 &mut self._attributes
299 }
300
301 pub fn write_outer_html<
303 W: fmt::Write,
304 const MAX_NODES: usize,
305 const MAX_STACK: usize,
306 const MAX_ROOTS: usize,
307 const MAX_IDS: usize,
308 const MAX_CLASSES: usize,
309 const MAX_SELECTOR_NODES: usize,
310 >(
311 &self,
312 parser: &Parser<
313 'a,
314 MAX_NODES,
315 MAX_STACK,
316 MAX_ROOTS,
317 MAX_IDS,
318 MAX_CLASSES,
319 MAX_SELECTOR_NODES,
320 >,
321 dest: &mut W,
322 ) -> fmt::Result {
323 let tag_name = self._name.try_as_utf8_str().unwrap_or("");
324 let is_void_element = HTML_VOID_ELEMENTS.contains(&tag_name);
325
326 dest.write_char('<')?;
327 dest.write_str(tag_name)?;
328
329 fn write_attribute<W: fmt::Write>(
330 dest: &mut W,
331 key: &Bytes<'_>,
332 value: Option<&Bytes<'_>>,
333 ) -> fmt::Result {
334 dest.write_char(' ')?;
335 dest.write_str(key.try_as_utf8_str().unwrap_or(""))?;
336
337 if let Some(value) = value {
338 dest.write_str("=\"")?;
339 dest.write_str(value.try_as_utf8_str().unwrap_or(""))?;
340 dest.write_char('"')?;
341 }
342
343 Ok(())
344 }
345
346 for (key, value) in self.attributes().raw.iter() {
347 write_attribute(dest, key, value.as_ref())?;
348 }
349 if let Some(id) = self.attributes().id() {
350 write_attribute(dest, &Bytes::from("id"), Some(id))?;
351 }
352 if let Some(class) = self.attributes().class() {
353 write_attribute(dest, &Bytes::from("class"), Some(class))?;
354 }
355
356 dest.write_char('>')?;
357
358 if !is_void_element {
359 self.write_inner_html(parser, dest)?;
360 dest.write_str("</")?;
361 dest.write_str(tag_name)?;
362 dest.write_char('>')?;
363 }
364
365 Ok(())
366 }
367
368 pub fn write_inner_html<
370 W: fmt::Write,
371 const MAX_NODES: usize,
372 const MAX_STACK: usize,
373 const MAX_ROOTS: usize,
374 const MAX_IDS: usize,
375 const MAX_CLASSES: usize,
376 const MAX_SELECTOR_NODES: usize,
377 >(
378 &self,
379 parser: &Parser<
380 'a,
381 MAX_NODES,
382 MAX_STACK,
383 MAX_ROOTS,
384 MAX_IDS,
385 MAX_CLASSES,
386 MAX_SELECTOR_NODES,
387 >,
388 dest: &mut W,
389 ) -> fmt::Result {
390 for handle in self.children().top().iter() {
391 if let Some(node) = handle.get(parser) {
392 node.write_outer_html(parser, dest)?;
393 }
394 }
395
396 Ok(())
397 }
398
399 #[cfg(feature = "std")]
407 pub fn outer_html<
408 'p,
409 const MAX_NODES: usize,
410 const MAX_STACK: usize,
411 const MAX_ROOTS: usize,
412 const MAX_IDS: usize,
413 const MAX_CLASSES: usize,
414 const MAX_SELECTOR_NODES: usize,
415 >(
416 &'p self,
417 parser: &'p Parser<
418 'a,
419 MAX_NODES,
420 MAX_STACK,
421 MAX_ROOTS,
422 MAX_IDS,
423 MAX_CLASSES,
424 MAX_SELECTOR_NODES,
425 >,
426 ) -> String {
427 let mut outer_html = String::with_capacity(self._raw.as_bytes().len());
428 let _ = self.write_outer_html(parser, &mut outer_html);
429 outer_html
430 }
431
432 #[cfg(feature = "std")]
440 pub fn inner_html<
441 'p,
442 const MAX_NODES: usize,
443 const MAX_STACK: usize,
444 const MAX_ROOTS: usize,
445 const MAX_IDS: usize,
446 const MAX_CLASSES: usize,
447 const MAX_SELECTOR_NODES: usize,
448 >(
449 &'p self,
450 parser: &'p Parser<
451 'a,
452 MAX_NODES,
453 MAX_STACK,
454 MAX_ROOTS,
455 MAX_IDS,
456 MAX_CLASSES,
457 MAX_SELECTOR_NODES,
458 >,
459 ) -> String {
460 let mut inner_html = String::with_capacity(self._raw.as_bytes().len());
461 let _ = self.write_inner_html(parser, &mut inner_html);
462 inner_html
463 }
464
465 pub fn raw(&self) -> &Bytes<'a> {
471 &self._raw
472 }
473
474 pub fn boundaries<
490 const MAX_NODES: usize,
491 const MAX_STACK: usize,
492 const MAX_ROOTS: usize,
493 const MAX_IDS: usize,
494 const MAX_CLASSES: usize,
495 const MAX_SELECTOR_NODES: usize,
496 >(
497 &self,
498 parser: &Parser<
499 'a,
500 MAX_NODES,
501 MAX_STACK,
502 MAX_ROOTS,
503 MAX_IDS,
504 MAX_CLASSES,
505 MAX_SELECTOR_NODES,
506 >,
507 ) -> (usize, usize) {
508 let raw = self._raw.as_bytes();
509 let input = parser.stream.data().as_ptr();
510 let start = raw.as_ptr();
511 let offset = start as usize - input as usize;
512 let end = offset + raw.len() - 1;
513 (offset, end)
514 }
515
516 #[cfg(feature = "std")]
521 pub fn inner_text<
522 'p,
523 const MAX_NODES: usize,
524 const MAX_STACK: usize,
525 const MAX_ROOTS: usize,
526 const MAX_IDS: usize,
527 const MAX_CLASSES: usize,
528 const MAX_SELECTOR_NODES: usize,
529 >(
530 &self,
531 parser: &'p Parser<
532 'a,
533 MAX_NODES,
534 MAX_STACK,
535 MAX_ROOTS,
536 MAX_IDS,
537 MAX_CLASSES,
538 MAX_SELECTOR_NODES,
539 >,
540 ) -> Cow<'p, str> {
541 let len = self._children.len();
542
543 if len == 0 {
544 return Cow::Borrowed("");
546 }
547
548 let first = self._children[0].get(parser).unwrap();
549
550 if len == 1 {
551 match &first {
552 Node::Tag(t) => return t.inner_text(parser),
553 Node::Raw(e) => return e.as_utf8_str(),
554 Node::Comment(_) => return Cow::Borrowed(""),
555 }
556 }
557
558 let mut s = String::from(first.inner_text(parser));
561
562 for &id in self._children.iter().skip(1) {
563 let node = id.get(parser).unwrap();
564
565 match &node {
566 Node::Tag(t) => s.push_str(&t.inner_text(parser)),
567 Node::Raw(e) => s.push_str(&e.as_utf8_str()),
568 Node::Comment(_) => { }
569 }
570 }
571
572 Cow::Owned(s)
573 }
574
575 #[cfg(feature = "std")]
613 pub fn query_selector<
614 'b,
615 const MAX_NODES: usize,
616 const MAX_STACK: usize,
617 const MAX_ROOTS: usize,
618 const MAX_IDS: usize,
619 const MAX_CLASSES: usize,
620 >(
621 &'b self,
622 parser: &'b Parser<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, 0>,
623 selector: &'b str,
624 ) -> Option<
625 QuerySelectorIterator<
626 'a,
627 'b,
628 Self,
629 MAX_NODES,
630 MAX_STACK,
631 MAX_ROOTS,
632 MAX_IDS,
633 MAX_CLASSES,
634 0,
635 >,
636 > {
637 let selector = crate::parse_query_selector(selector)?;
638 let iter = queryselector::QuerySelectorIterator::new(selector, parser, self);
639 Some(iter)
640 }
641
642 pub fn find_node<F>(&self, parser: &Parser<'a>, f: &mut F) -> Option<NodeHandle>
647 where
648 F: FnMut(&Node<'a>) -> bool,
649 {
650 for &id in self._children.iter() {
651 let node = id.get(parser).unwrap();
652
653 if f(node) {
654 return Some(id);
655 }
656 }
657 None
658 }
659}
660
661#[derive(Debug, Clone)]
663pub struct Children<'a, 'b>(&'b HTMLTag<'a>);
664
665impl<'a, 'b> Children<'a, 'b> {
666 #[inline]
705 pub fn top(&self) -> &RawChildren {
706 &self.0._children
707 }
708
709 #[inline]
711 pub fn start(&self) -> Option<InnerNodeHandle> {
712 self.0._children.get(0).map(NodeHandle::get_inner)
713 }
714
715 pub fn end<
717 const MAX_NODES: usize,
718 const MAX_STACK: usize,
719 const MAX_ROOTS: usize,
720 const MAX_IDS: usize,
721 const MAX_CLASSES: usize,
722 const MAX_SELECTOR_NODES: usize,
723 >(
724 &self,
725 parser: &Parser<
726 'a,
727 MAX_NODES,
728 MAX_STACK,
729 MAX_ROOTS,
730 MAX_IDS,
731 MAX_CLASSES,
732 MAX_SELECTOR_NODES,
733 >,
734 ) -> Option<InnerNodeHandle> {
735 find_last_node_handle(self.0, parser).map(|h| h.get_inner())
736 }
737
738 #[inline]
740 pub fn boundaries<
741 const MAX_NODES: usize,
742 const MAX_STACK: usize,
743 const MAX_ROOTS: usize,
744 const MAX_IDS: usize,
745 const MAX_CLASSES: usize,
746 const MAX_SELECTOR_NODES: usize,
747 >(
748 &self,
749 parser: &Parser<
750 'a,
751 MAX_NODES,
752 MAX_STACK,
753 MAX_ROOTS,
754 MAX_IDS,
755 MAX_CLASSES,
756 MAX_SELECTOR_NODES,
757 >,
758 ) -> Option<(InnerNodeHandle, InnerNodeHandle)> {
759 self.start().zip(self.end(parser))
760 }
761
762 pub fn all<
796 const MAX_NODES: usize,
797 const MAX_STACK: usize,
798 const MAX_ROOTS: usize,
799 const MAX_IDS: usize,
800 const MAX_CLASSES: usize,
801 const MAX_SELECTOR_NODES: usize,
802 >(
803 &self,
804 parser: &'b Parser<
805 'a,
806 MAX_NODES,
807 MAX_STACK,
808 MAX_ROOTS,
809 MAX_IDS,
810 MAX_CLASSES,
811 MAX_SELECTOR_NODES,
812 >,
813 ) -> &'b [Node<'a>] {
814 self.boundaries(parser)
815 .map(|(start, end)| &parser.tags.as_slice()[start as usize..=end as usize])
816 .unwrap_or(&[])
817 }
818}
819
820#[derive(Debug)]
822pub struct ChildrenMut<'a, 'b>(&'b mut HTMLTag<'a>);
823
824impl<'a, 'b> ChildrenMut<'a, 'b> {
825 #[inline]
829 pub fn top_mut(&mut self) -> &mut RawChildren {
830 &mut self.0._children
831 }
832}
833
834fn find_last_node_handle<
836 'a,
837 const MAX_NODES: usize,
838 const MAX_STACK: usize,
839 const MAX_ROOTS: usize,
840 const MAX_IDS: usize,
841 const MAX_CLASSES: usize,
842 const MAX_SELECTOR_NODES: usize,
843>(
844 tag: &HTMLTag<'a>,
845 parser: &Parser<'a, MAX_NODES, MAX_STACK, MAX_ROOTS, MAX_IDS, MAX_CLASSES, MAX_SELECTOR_NODES>,
846) -> Option<NodeHandle> {
847 let last_handle = tag._children.as_slice().last().copied()?;
848
849 let child = last_handle
850 .get(parser)
851 .expect("Failed to get child node, please open a bug report") .as_tag();
853
854 if let Some(child) = child {
855 find_last_node_handle(child, parser).or(Some(last_handle))
857 } else {
858 Some(last_handle)
859 }
860}
861
862#[derive(Debug, Clone)]
864#[allow(clippy::large_enum_variant)]
865pub enum Node<'a> {
866 Tag(HTMLTag<'a>),
868 Raw(Bytes<'a>),
870 Comment(Bytes<'a>),
872}
873
874impl<'a> Node<'a> {
875 pub fn write_outer_html<
877 W: fmt::Write,
878 const MAX_NODES: usize,
879 const MAX_STACK: usize,
880 const MAX_ROOTS: usize,
881 const MAX_IDS: usize,
882 const MAX_CLASSES: usize,
883 const MAX_SELECTOR_NODES: usize,
884 >(
885 &self,
886 parser: &Parser<
887 'a,
888 MAX_NODES,
889 MAX_STACK,
890 MAX_ROOTS,
891 MAX_IDS,
892 MAX_CLASSES,
893 MAX_SELECTOR_NODES,
894 >,
895 dest: &mut W,
896 ) -> fmt::Result {
897 match self {
898 Node::Comment(c) | Node::Raw(c) => dest.write_str(c.try_as_utf8_str().unwrap_or("")),
899 Node::Tag(t) => t.write_outer_html(parser, dest),
900 }
901 }
902
903 #[cfg(feature = "std")]
905 pub fn inner_text<
906 's,
907 'p: 's,
908 const MAX_NODES: usize,
909 const MAX_STACK: usize,
910 const MAX_ROOTS: usize,
911 const MAX_IDS: usize,
912 const MAX_CLASSES: usize,
913 const MAX_SELECTOR_NODES: usize,
914 >(
915 &'s self,
916 parser: &'p Parser<
917 'a,
918 MAX_NODES,
919 MAX_STACK,
920 MAX_ROOTS,
921 MAX_IDS,
922 MAX_CLASSES,
923 MAX_SELECTOR_NODES,
924 >,
925 ) -> Cow<'s, str> {
926 match self {
927 Node::Comment(_) => Cow::Borrowed(""),
928 Node::Raw(r) => r.as_utf8_str(),
929 Node::Tag(t) => t.inner_text(parser),
930 }
931 }
932
933 #[cfg(feature = "std")]
935 pub fn outer_html<
936 's,
937 const MAX_NODES: usize,
938 const MAX_STACK: usize,
939 const MAX_ROOTS: usize,
940 const MAX_IDS: usize,
941 const MAX_CLASSES: usize,
942 const MAX_SELECTOR_NODES: usize,
943 >(
944 &'s self,
945 parser: &Parser<
946 'a,
947 MAX_NODES,
948 MAX_STACK,
949 MAX_ROOTS,
950 MAX_IDS,
951 MAX_CLASSES,
952 MAX_SELECTOR_NODES,
953 >,
954 ) -> Cow<'s, str> {
955 match self {
956 Node::Comment(c) => c.as_utf8_str(),
957 Node::Raw(r) => r.as_utf8_str(),
958 Node::Tag(t) => Cow::Owned(t.outer_html(parser)),
959 }
960 }
961
962 #[cfg(feature = "std")]
964 pub fn inner_html<
965 's,
966 const MAX_NODES: usize,
967 const MAX_STACK: usize,
968 const MAX_ROOTS: usize,
969 const MAX_IDS: usize,
970 const MAX_CLASSES: usize,
971 const MAX_SELECTOR_NODES: usize,
972 >(
973 &'s self,
974 parser: &Parser<
975 'a,
976 MAX_NODES,
977 MAX_STACK,
978 MAX_ROOTS,
979 MAX_IDS,
980 MAX_CLASSES,
981 MAX_SELECTOR_NODES,
982 >,
983 ) -> Cow<'s, str> {
984 match self {
985 Node::Comment(c) => c.as_utf8_str(),
986 Node::Raw(r) => r.as_utf8_str(),
987 Node::Tag(t) => Cow::Owned(t.inner_html(parser)),
988 }
989 }
990
991 pub fn children(&self) -> Option<Children<'a, '_>> {
993 match self {
994 Node::Tag(t) => Some(t.children()),
995 _ => None,
996 }
997 }
998
999 pub fn find_node<F>(&self, parser: &Parser<'a>, f: &mut F) -> Option<NodeHandle>
1004 where
1005 F: FnMut(&Node<'a>) -> bool,
1006 {
1007 if let Some(children) = self.children() {
1008 for &id in children.top().iter() {
1009 let node = id.get(parser).unwrap();
1010
1011 if f(node) {
1012 return Some(id);
1013 }
1014
1015 let subnode = node.find_node(parser, f);
1016 if subnode.is_some() {
1017 return subnode;
1018 }
1019 }
1020 }
1021 None
1022 }
1023
1024 pub fn as_tag(&self) -> Option<&HTMLTag<'a>> {
1026 match self {
1027 Self::Tag(tag) => Some(tag),
1028 _ => None,
1029 }
1030 }
1031
1032 pub fn as_tag_mut(&mut self) -> Option<&mut HTMLTag<'a>> {
1034 match self {
1035 Self::Tag(tag) => Some(tag),
1036 _ => None,
1037 }
1038 }
1039
1040 pub fn as_comment(&self) -> Option<&Bytes<'a>> {
1042 match self {
1043 Self::Comment(c) => Some(c),
1044 _ => None,
1045 }
1046 }
1047
1048 pub fn as_comment_mut(&mut self) -> Option<&mut Bytes<'a>> {
1050 match self {
1051 Self::Comment(c) => Some(c),
1052 _ => None,
1053 }
1054 }
1055
1056 pub fn as_raw(&self) -> Option<&Bytes<'a>> {
1060 match self {
1061 Self::Raw(r) => Some(r),
1062 _ => None,
1063 }
1064 }
1065
1066 pub fn as_raw_mut(&mut self) -> Option<&mut Bytes<'a>> {
1070 match self {
1071 Self::Raw(r) => Some(r),
1072 _ => None,
1073 }
1074 }
1075}