1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Match {
8 pub cell_index: usize,
10
11 pub cell_number: usize,
13
14 pub execution_count: Option<i32>,
16
17 pub match_type: MatchType,
19
20 pub line_index: usize,
22
23 pub line_number: usize,
25
26 pub line_content: String,
28
29 pub matched_text: String,
31
32 #[serde(skip_serializing_if = "Vec::is_empty", default)]
34 pub context_before: Vec<String>,
35
36 #[serde(skip_serializing_if = "Vec::is_empty", default)]
38 pub context_after: Vec<String>,
39}
40
41impl Match {
42 pub fn new(
44 cell_index: usize,
45 execution_count: Option<i32>,
46 match_type: MatchType,
47 line_index: usize,
48 line_content: String,
49 matched_text: String,
50 ) -> Self {
51 Self {
52 cell_index,
53 cell_number: cell_index + 1,
54 execution_count,
55 match_type,
56 line_index,
57 line_number: line_index + 1,
58 line_content,
59 matched_text,
60 context_before: Vec::new(),
61 context_after: Vec::new(),
62 }
63 }
64}
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
68#[serde(rename_all = "lowercase")]
69pub enum MatchType {
70 Input,
72 Output,
74}
75
76impl std::fmt::Display for MatchType {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 match self {
79 MatchType::Input => write!(f, "input"),
80 MatchType::Output => write!(f, "output"),
81 }
82 }
83}
84
85#[derive(Debug, Clone)]
87pub struct GrepOptions {
88 pub pattern: String,
90
91 pub case_insensitive: bool,
93
94 pub search_inputs: bool,
96
97 pub search_outputs: bool,
99
100 pub context_lines: Option<usize>,
102
103 pub context_before: Option<usize>,
105
106 pub context_after: Option<usize>,
108
109 pub word_regexp: bool,
111
112 pub fixed_strings: bool,
114
115 pub only_matching: bool,
117
118 pub invert_match: bool,
120
121 pub max_count: Option<usize>,
123
124 pub code_cells_only: bool,
126
127 pub markdown_cells_only: bool,
129
130 pub raw_cells_only: bool,
132
133 pub executed_only: bool,
135
136 pub not_executed_only: bool,
138
139 pub stream_output_only: bool,
141
142 pub error_output_only: bool,
144
145 pub result_output_only: bool,
147
148 pub glob_pattern: Option<String>,
150
151 pub exclude_pattern: Option<String>,
153}
154
155impl Default for GrepOptions {
156 fn default() -> Self {
157 Self {
158 pattern: String::new(),
159 case_insensitive: false,
160 search_inputs: true,
161 search_outputs: true,
162 context_lines: None,
163 context_before: None,
164 context_after: None,
165 word_regexp: false,
166 fixed_strings: false,
167 only_matching: false,
168 invert_match: false,
169 max_count: None,
170 code_cells_only: false,
171 markdown_cells_only: false,
172 raw_cells_only: false,
173 executed_only: false,
174 not_executed_only: false,
175 stream_output_only: false,
176 error_output_only: false,
177 result_output_only: false,
178 glob_pattern: None,
179 exclude_pattern: None,
180 }
181 }
182}
183
184#[derive(Debug, Clone, Serialize)]
186pub struct GrepResult {
187 pub notebook: String,
189
190 pub matches: Vec<Match>,
192}
193
194impl GrepResult {
195 pub fn new(notebook: String) -> Self {
196 Self {
197 notebook,
198 matches: Vec::new(),
199 }
200 }
201
202 pub fn is_empty(&self) -> bool {
203 self.matches.is_empty()
204 }
205
206 pub fn match_count(&self) -> usize {
207 self.matches.len()
208 }
209}