ziyy_core/parser/
chunk.rs1use std::{
2 borrow::Cow,
3 fmt::Display,
4 ops::{Deref, DerefMut},
5};
6
7use crate::common::Span;
8
9use super::tag_parser::tag::Tag;
10
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum ChunkData<'a> {
13 Tag(Tag),
14 WhiteSpace(Cow<'a, str>),
15 Word(Cow<'a, str>),
16}
17
18impl<'a> ChunkData<'a> {
19 pub fn is_tag(&self) -> bool {
20 matches!(self, ChunkData::Tag(_))
21 }
22
23 pub fn is_tag_and<F>(&self, f: F) -> bool
24 where
25 F: FnOnce(&Tag) -> bool,
26 {
27 match self {
28 ChunkData::Tag(tag) => f(tag),
29 _ => false,
30 }
31 }
32
33 pub fn is_word(&self) -> bool {
34 matches!(self, ChunkData::Word(_))
35 }
36
37 pub fn is_ws(&self) -> bool {
38 matches!(self, ChunkData::WhiteSpace(_))
39 }
40
41 pub fn tag(&self) -> Option<&Tag> {
42 if let ChunkData::Tag(tag) = self {
43 Some(tag)
44 } else {
45 None
46 }
47 }
48
49 pub fn word(&self) -> Option<&Cow<'a, str>> {
50 if let ChunkData::Word(word) = self {
51 Some(word)
52 } else {
53 None
54 }
55 }
56
57 pub fn ws(&self) -> Option<&Cow<'a, str>> {
58 if let ChunkData::WhiteSpace(ws) = self {
59 Some(ws)
60 } else {
61 None
62 }
63 }
64
65 pub fn tag_mut(&mut self) -> Option<&mut Tag> {
66 if let ChunkData::Tag(tag) = self {
67 Some(tag)
68 } else {
69 None
70 }
71 }
72}
73
74impl<'a> Display for ChunkData<'a> {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 if f.alternate() {
77 match self {
78 ChunkData::Tag(tag) => f.write_fmt(format_args!("{tag:#}")),
79 ChunkData::WhiteSpace(ws) => f.write_fmt(format_args!("{ws:?}")),
80 ChunkData::Word(word) => f.write_fmt(format_args!("{word:?}")),
81 }
82 } else {
83 match self {
84 ChunkData::Tag(tag) => tag.fmt(f),
85 ChunkData::WhiteSpace(ws) => ws.fmt(f),
86 ChunkData::Word(word) => word.fmt(f),
87 }
88 }
89 }
90}
91
92#[derive(Debug, Clone, PartialEq)]
93
94pub struct Chunk<'a> {
95 pub data: ChunkData<'a>,
96 pub span: Span,
97}
98
99impl<'a> Deref for Chunk<'a> {
100 type Target = ChunkData<'a>;
101
102 fn deref(&self) -> &Self::Target {
103 &self.data
104 }
105}
106
107impl<'a> DerefMut for Chunk<'a> {
108 fn deref_mut(&mut self) -> &mut Self::Target {
109 &mut self.data
110 }
111}
112
113impl<'a> Display for Chunk<'a> {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 if f.alternate() {
116 f.write_fmt(format_args!(
117 "{:#} \x1b[38;5;59m--> {}\x1b[39m",
118 self.data, self.span
119 ))
120 } else {
121 self.data.fmt(f)
122 }
123 }
124}