ziyy_core/parser/
chunk.rs

1use 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}