1pub mod injector;
2pub mod query;
3pub mod variants;
4mod worker;
5
6use std::{
7 borrow::Cow,
8 fmt::{self, Display, Formatter},
9 hash::{Hash, Hasher},
10 ops::Range,
11};
12
13use arrayvec::ArrayVec;
14pub use variants::*;
15pub use worker::*;
16
17pub use nucleo;
18pub use ratatui::prelude::*;
19
20use crate::{MAX_SPLITS, SSS};
21
22pub trait SegmentableItem: SSS {
24 fn slice(&self, range: Range<usize>) -> ratatui::text::Text<'_>;
25}
26
27impl SegmentableItem for String {
28 fn slice(&self, range: Range<usize>) -> ratatui::text::Text<'_> {
29 ratatui::text::Text::from(&self[range])
30 }
31}
32
33#[derive(Debug, Clone, Hash, Eq, PartialEq)]
35pub struct Segmented<T> {
36 pub inner: T,
37 ranges: ArrayVec<(usize, usize), MAX_SPLITS>,
38}
39
40impl<T: SegmentableItem> ColumnIndexable for Segmented<T> {
41 fn get_text(&self, i: usize) -> Text<'_> {
51 if let Some((start, end)) = self.ranges.get(i) {
52 self.inner.slice(*start..*end)
53 } else {
54 Text::default()
55 }
56 }
57}
58
59impl<T: SegmentableItem> Segmented<T> {
60 pub fn len(&self) -> usize {
61 self.ranges
63 .iter()
64 .rposition(|&(start, end)| start != end)
65 .map_or(0, |idx| idx + 1)
66 }
67
68 pub fn is_empty(&self) -> bool {
69 self.len() == 0
70 }
71
72 pub fn map_to_vec<U, F>(&self, f: F) -> ArrayVec<U, MAX_SPLITS>
73 where
74 F: Fn(&T, usize, usize) -> U,
75 {
76 self.ranges
77 .iter()
78 .take(self.len()) .map(|&(start, end)| f(&self.inner, start, end))
80 .collect()
81 }
82}
83
84impl<T> std::ops::Deref for Segmented<T> {
85 type Target = T;
86
87 fn deref(&self) -> &Self::Target {
88 &self.inner
89 }
90}
91
92#[derive(Debug, Clone)]
95pub struct Indexed<T> {
96 pub index: u32,
97 pub inner: T,
98}
99
100impl<T: Clone> Indexed<T> {
101 pub fn identifier(&self) -> (u32, T) {
103 (self.index, self.inner.clone())
104 }
105}
106
107impl<T> Indexed<T> {
108 pub fn dummy_identifier(&self) -> (u32, ()) {
110 (self.index, ())
111 }
112}
113
114impl<T: ColumnIndexable> ColumnIndexable for Indexed<T> {
115 fn get_str(&self, index: usize) -> Cow<'_, str> {
116 self.inner.get_str(index)
117 }
118
119 fn get_text(&self, i: usize) -> Text<'_> {
120 self.inner.get_text(i)
121 }
122}
123
124impl<T: Render> Render for Indexed<T> {
125 fn as_str(&self) -> Cow<'_, str> {
126 self.inner.as_str()
127 }
128 fn as_text(&self) -> Text<'_> {
129 self.inner.as_text()
130 }
131}
132
133impl<T> std::ops::Deref for Indexed<T> {
134 type Target = T;
135
136 fn deref(&self) -> &Self::Target {
137 &self.inner
138 }
139}
140
141impl<T: Display + SegmentableItem> Display for Segmented<T> {
143 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
144 write!(f, "{}", self.inner)
145 }
146}
147
148impl<T: Display> Display for Indexed<T> {
149 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
150 write!(f, "{}", self.inner)
151 }
152}
153
154impl<T> PartialEq for Indexed<T> {
155 fn eq(&self, other: &Self) -> bool {
156 self.index == other.index
157 }
158}
159
160impl<T> Eq for Indexed<T> {}
161
162impl<T> Hash for Indexed<T> {
163 fn hash<H: Hasher>(&self, state: &mut H) {
164 self.index.hash(state)
165 }
166}