1use matchmaker_partial_macros::partial;
5
6pub use crate::config_types::*;
7pub use crate::utils::{Percentage, serde::StringOrVec};
8
9use crate::{
10 MAX_SPLITS,
11 tui::IoStream,
12 utils::serde::{escaped_opt_char, escaped_opt_string, serde_duration_ms},
13};
14
15use cba::serde::transform::{camelcase_normalized, camelcase_normalized_option};
16use ratatui::{
17 style::{Color, Modifier, Style},
18 text::Span,
19 widgets::{BorderType, Borders},
20};
21
22use serde::{Deserialize, Serialize};
23
24#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
28#[partial(recurse, path, derive(Debug, Deserialize))]
29pub struct MatcherConfig {
30 #[serde(flatten)]
31 #[partial(skip)]
32 pub matcher: NucleoMatcherConfig,
33 #[serde(flatten)]
34 pub worker: WorkerConfig,
35}
36
37#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
41#[serde(default)]
42#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
43pub struct WorkerConfig {
44 #[partial(recurse)]
45 #[serde(flatten)]
46 pub columns: ColumnsConfig,
48 pub sort_threshold: u32,
50 #[partial(alias = "i")]
52 pub default_column: Option<String>,
53
54 #[partial(alias = "r")]
56 pub raw: bool,
57 pub track: bool,
59 pub reverse: bool, }
62
63#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
66#[serde(default, deny_unknown_fields)]
67#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
68pub struct StartConfig {
69 #[serde(deserialize_with = "escaped_opt_char")]
70 #[partial(alias = "is")]
71 pub input_separator: Option<char>,
72 #[serde(deserialize_with = "escaped_opt_string")]
73 #[partial(alias = "os")]
74 pub output_separator: Option<String>,
75
76 #[partial(alias = "ot")]
78 #[serde(alias = "output")]
79 pub output_template: Option<String>,
80
81 #[partial(alias = "cmd", alias = "x")]
83 pub command: String,
84 #[partial(alias = "ax")]
86 pub additional_commands: Vec<String>,
87 pub sync: bool,
88
89 #[partial(alias = "a")]
91 pub ansi: bool,
92 #[partial(alias = "t")]
94 pub trim: bool,
95}
96
97#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
99#[serde(default, deny_unknown_fields)]
100#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
101pub struct ExitConfig {
102 pub select_1: bool,
104 pub allow_empty: bool,
106 pub abort_empty: bool,
108 pub last_key_path: Option<std::path::PathBuf>,
111}
112
113#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
115#[serde(default, deny_unknown_fields)]
116#[partial(recurse, path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
117pub struct RenderConfig {
118 pub ui: UiConfig,
120 #[partial(alias = "i")]
122 pub input: InputConfig,
123 #[partial(alias = "r")]
125 pub results: ResultsConfig,
126
127 pub status: StatusConfig,
129 #[partial(alias = "p")]
131 pub preview: PreviewConfig,
132 #[partial(alias = "f")]
133 pub footer: DisplayConfig,
134 #[partial(alias = "h")]
135 pub header: DisplayConfig,
136}
137
138impl RenderConfig {
139 pub fn tick_rate(&self) -> u8 {
140 self.ui.tick_rate
141 }
142}
143
144#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
146#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
147#[serde(default, deny_unknown_fields)]
148pub struct TerminalConfig {
149 pub stream: IoStream, pub restore_fullscreen: bool,
151 pub redraw_on_resize: bool,
152 pub extended_keys: bool,
154 #[serde(with = "serde_duration_ms")]
155 pub sleep_ms: std::time::Duration, #[serde(flatten)]
157 #[partial(recurse)]
158 pub layout: Option<TerminalLayoutSettings>, pub clear_on_exit: bool,
160 pub move_up_on_exit: bool,
162}
163
164impl Default for TerminalConfig {
165 fn default() -> Self {
166 Self {
167 stream: IoStream::default(),
168 restore_fullscreen: true,
169 redraw_on_resize: bool::default(),
170 sleep_ms: std::time::Duration::default(),
171 layout: Option::default(),
172 extended_keys: true,
173 clear_on_exit: true,
174 move_up_on_exit: false,
175 }
176 }
177}
178
179#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
181#[serde(default, deny_unknown_fields)]
182#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
183pub struct UiConfig {
184 #[partial(recurse)]
185 pub border: BorderSetting,
186 pub tick_rate: u8, }
188
189impl Default for UiConfig {
190 fn default() -> Self {
191 Self {
192 border: Default::default(),
193 tick_rate: 60,
194 }
195 }
196}
197
198#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
200#[serde(default, deny_unknown_fields)]
201#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
202pub struct InputConfig {
203 #[partial(recurse)]
204 pub border: BorderSetting,
205
206 #[serde(deserialize_with = "camelcase_normalized")]
208 pub fg: Color,
209 pub modifier: Modifier,
211
212 #[serde(deserialize_with = "camelcase_normalized")]
213 pub prompt_fg: Color,
214 pub prompt_bg: Color,
215 pub prompt_modifier: Modifier,
217
218 #[serde(deserialize_with = "deserialize_string_or_char_as_double_width")]
220 pub prompt: String,
221 pub cursor: CursorSetting,
223
224 #[partial(alias = "i")]
226 pub initial: String,
227
228 pub scroll_padding: bool,
230}
231
232impl Default for InputConfig {
233 fn default() -> Self {
234 Self {
235 border: Default::default(),
236 fg: Default::default(),
237 modifier: Default::default(),
238 prompt_fg: Default::default(),
239 prompt_bg: Default::default(),
240 prompt_modifier: Default::default(),
241 prompt: "> ".to_string(),
242 cursor: Default::default(),
243 initial: Default::default(),
244
245 scroll_padding: true,
246 }
247 }
248}
249
250impl InputConfig {
251 pub fn text_style(&self) -> Style {
252 Style::default().fg(self.fg).add_modifier(self.modifier)
253 }
254
255 pub fn prompt_style(&self) -> Style {
256 Style::default()
257 .fg(self.prompt_fg)
258 .bg(self.prompt_bg)
259 .add_modifier(self.prompt_modifier)
260 }
261}
262
263#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
264#[serde(default, deny_unknown_fields)]
265#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
266pub struct OverlayConfig {
267 #[partial(recurse)]
268 pub border: BorderSetting,
269 pub outer_dim: bool,
270 pub layout: OverlayLayoutSettings,
271}
272
273#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
274#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
275pub struct OverlayLayoutSettings {
276 #[partial(alias = "p")]
278 pub percentage: [Percentage; 2],
279 pub min: [u16; 2],
281 pub max: [u16; 2],
283
284 pub y_offset: Percentage,
286}
287
288impl Default for OverlayLayoutSettings {
289 fn default() -> Self {
290 Self {
291 percentage: [Percentage::new(60), Percentage::new(30)],
292 min: [10, 10],
293 max: [200, 30],
294 y_offset: Percentage::new(55),
295 }
296 }
297}
298
299#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
302#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
303#[serde(default, deny_unknown_fields)]
304pub struct ResultsConfig {
305 #[partial(recurse)]
306 pub border: BorderSetting,
307
308 #[serde(deserialize_with = "deserialize_string_or_char_as_double_width")]
310 pub multi_prefix: String,
311 pub default_prefix: String,
312
313 pub multi: bool,
315
316 #[serde(deserialize_with = "camelcase_normalized")]
318 pub fg: Color,
319 #[serde(deserialize_with = "camelcase_normalized")]
320 pub bg: Color,
321 pub modifier: Modifier,
323
324 #[serde(deserialize_with = "camelcase_normalized")]
326 pub inactive_fg: Color,
327 #[serde(deserialize_with = "camelcase_normalized")]
328 pub inactive_bg: Color,
329 pub inactive_modifier: Modifier,
331
332 #[serde(deserialize_with = "camelcase_normalized")]
334 pub inactive_current_fg: Color,
335 #[serde(deserialize_with = "camelcase_normalized")]
336 pub inactive_current_bg: Color,
337 pub inactive_current_modifier: Modifier,
339
340 #[serde(deserialize_with = "camelcase_normalized")]
341 pub match_fg: Color,
342 pub match_modifier: Modifier,
344
345 #[serde(deserialize_with = "camelcase_normalized")]
347 pub current_fg: Color,
348 #[serde(deserialize_with = "camelcase_normalized")]
350 pub current_bg: Color,
351 pub current_modifier: Modifier,
354
355 #[serde(deserialize_with = "camelcase_normalized")]
360 pub row_connection_style: RowConnectionStyle,
361
362 #[partial(alias = "c")]
364 #[serde(alias = "cycle")]
365 pub scroll_wrap: bool,
366 #[partial(alias = "sp")]
367 pub scroll_padding: u16,
368 #[partial(alias = "r")]
369 pub reverse: Option<bool>,
370
371 #[partial(alias = "w")]
373 pub wrap: bool,
374 pub min_wrap_width: u16,
375
376 pub autoscroll_initial_preserved: usize,
378 pub autoscroll: bool,
379 pub autoscroll_context: usize,
380
381 pub column_spacing: Count,
385 pub current_prefix: String,
386
387 #[partial(alias = "ra")]
389 pub right_align_last: bool,
390
391 #[partial(alias = "v")]
392 #[serde(alias = "vertical")]
393 pub stacked_columns: bool,
394
395 #[serde(alias = "hr")]
396 #[serde(deserialize_with = "camelcase_normalized")]
397 pub horizontal_separator: HorizontalSeparator,
398}
399
400impl Default for ResultsConfig {
401 fn default() -> Self {
402 ResultsConfig {
403 border: Default::default(),
404
405 multi_prefix: "▌ ".to_string(),
406 default_prefix: Default::default(),
407 multi: true,
408
409 fg: Default::default(),
410 modifier: Default::default(),
411 bg: Default::default(),
412
413 inactive_fg: Default::default(),
414 inactive_modifier: Modifier::DIM,
415 inactive_bg: Default::default(),
416
417 inactive_current_fg: Default::default(),
418 inactive_current_modifier: Default::default(),
419 inactive_current_bg: Default::default(),
420
421 match_fg: Color::Green,
422 match_modifier: Modifier::ITALIC,
423
424 current_fg: Default::default(),
425 current_bg: Color::Black,
426 current_modifier: Modifier::BOLD,
427 row_connection_style: RowConnectionStyle::Disjoint,
428
429 scroll_wrap: true,
430 scroll_padding: 2,
431 reverse: Default::default(),
432
433 wrap: Default::default(),
434 min_wrap_width: 6,
435
436 autoscroll: true,
437 autoscroll_initial_preserved: 0,
438 autoscroll_context: 4,
439
440 column_spacing: Default::default(),
441 current_prefix: Default::default(),
442 right_align_last: false,
443 stacked_columns: false,
444 horizontal_separator: Default::default(),
445 }
446 }
447}
448
449#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
450#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
451#[serde(default, deny_unknown_fields)]
452pub struct StatusConfig {
453 #[serde(deserialize_with = "camelcase_normalized")]
454 pub fg: Color,
455 #[serde(deserialize_with = "camelcase_normalized")]
456 pub bg: Color,
457 pub modifier: Modifier,
459
460 pub show: bool,
462 pub match_indent: bool,
464
465 #[partial(alias = "t")]
471 pub template: String,
472
473 pub row_connection_style: RowConnectionStyle,
477}
478impl Default for StatusConfig {
479 fn default() -> Self {
480 Self {
481 fg: Color::Green,
482 bg: Default::default(),
483 modifier: Modifier::ITALIC,
484 show: true,
485 match_indent: true,
486 template: r#"\m/\t"#.to_string(),
487 row_connection_style: RowConnectionStyle::Full,
488 }
489 }
490}
491
492impl StatusConfig {
493 pub fn base_style(&self) -> Style {
494 Style::default()
495 .fg(self.fg)
496 .bg(self.bg)
497 .add_modifier(self.modifier)
498 }
499}
500
501#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
502#[serde(default, deny_unknown_fields)]
503#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
504pub struct DisplayConfig {
505 #[partial(recurse)]
506 pub border: BorderSetting,
507
508 #[serde(deserialize_with = "camelcase_normalized")]
509 pub fg: Color,
510 pub modifier: Modifier,
512
513 pub match_indent: bool,
515 pub wrap: bool,
517
518 pub content: Option<StringOrVec>,
520
521 #[serde(deserialize_with = "camelcase_normalized")]
530 pub row_connection_style: RowConnectionStyle,
531
532 #[partial(alias = "h")]
534 pub header_lines: usize,
535}
536
537impl Default for DisplayConfig {
538 fn default() -> Self {
539 DisplayConfig {
540 border: Default::default(),
541 match_indent: true,
542 fg: Color::Green,
543 wrap: false,
544 row_connection_style: Default::default(),
545 modifier: Modifier::ITALIC, content: None,
547 header_lines: 0,
548 }
549 }
550}
551
552#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
568#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
569#[serde(default)]
570pub struct PreviewConfig {
571 #[partial(recurse)]
572 pub border: BorderSetting,
573 #[partial(recurse, set = "recurse")]
574 #[partial(alias = "l")]
575 pub layout: Vec<PreviewSetting>,
576 #[partial(recurse)]
577 #[serde(flatten)]
578 pub scroll: PreviewScrollSetting,
579 #[partial(alias = "c")]
581 #[serde(alias = "cycle")]
582 pub scroll_wrap: bool,
583 pub wrap: bool,
584 pub show: ShowCondition,
587
588 pub reevaluate_show_on_resize: bool,
589}
590
591impl Default for PreviewConfig {
592 fn default() -> Self {
593 PreviewConfig {
594 border: BorderSetting {
595 padding: Padding(ratatui::widgets::Padding::left(2)),
596 ..Default::default()
597 },
598 scroll: Default::default(),
599 layout: Default::default(),
600 scroll_wrap: true,
601 wrap: Default::default(),
602 show: Default::default(),
603 reevaluate_show_on_resize: false,
604 }
605 }
606}
607
608#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
610#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
611#[serde(default, deny_unknown_fields)]
612pub struct PreviewScrollSetting {
613 pub index: Option<String>,
616 #[partial(alias = "o")]
618 pub offset: isize,
619 #[partial(alias = "p")]
621 pub percentage: Percentage,
622 #[partial(alias = "h")]
624 pub header_lines: usize,
625}
626
627impl Default for PreviewScrollSetting {
628 fn default() -> Self {
629 Self {
630 index: Default::default(),
631 offset: -1,
632 percentage: Default::default(),
633 header_lines: Default::default(),
634 }
635 }
636}
637
638#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
639#[serde(default, deny_unknown_fields)]
640pub struct PreviewerConfig {
641 pub try_lossy: bool,
642
643 pub cache: u8,
645
646 pub help_colors: HelpColorConfig,
647}
648
649#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
651pub struct HelpColorConfig {
652 #[serde(deserialize_with = "camelcase_normalized")]
653 pub section: Color,
654 #[serde(deserialize_with = "camelcase_normalized")]
655 pub key: Color,
656 #[serde(deserialize_with = "camelcase_normalized")]
657 pub value: Color,
658}
659
660impl Default for HelpColorConfig {
661 fn default() -> Self {
662 Self {
663 section: Color::Blue,
664 key: Color::Green,
665 value: Color::White,
666 }
667 }
668}
669
670#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
673#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
674#[serde(default, deny_unknown_fields)]
675pub struct BorderSetting {
676 #[serde(deserialize_with = "camelcase_normalized_option")]
677 pub r#type: Option<BorderType>,
678 #[serde(deserialize_with = "camelcase_normalized")]
679 pub color: Color,
680 pub sides: Option<Borders>,
689 pub padding: Padding,
697 pub title: String,
698 pub title_modifier: Modifier,
700 pub modifier: Modifier,
701 #[serde(deserialize_with = "camelcase_normalized")]
702 pub bg: Color,
703}
704
705impl BorderSetting {
706 pub fn as_block(&self) -> ratatui::widgets::Block<'_> {
707 let mut ret = ratatui::widgets::Block::default()
708 .padding(self.padding.0)
709 .style(Style::default().bg(self.bg).add_modifier(self.modifier));
710
711 if !self.title.is_empty() {
712 let title = Span::styled(
713 &self.title,
714 Style::default().add_modifier(self.title_modifier),
715 );
716
717 ret = ret.title(title)
718 };
719
720 if !self.is_empty() {
721 ret = ret
722 .borders(self.sides())
723 .border_type(self.r#type.unwrap_or_default())
724 .border_style(ratatui::style::Style::default().fg(self.color))
725 }
726
727 ret
728 }
729
730 pub fn sides(&self) -> Borders {
731 if let Some(s) = self.sides {
732 s
733 } else if self.color != Default::default() || self.r#type != Default::default() {
734 Borders::ALL
735 } else {
736 Borders::NONE
737 }
738 }
739
740 pub fn as_static_block(&self) -> ratatui::widgets::Block<'static> {
741 let mut ret = ratatui::widgets::Block::default()
742 .padding(self.padding.0)
743 .style(Style::default().bg(self.bg).add_modifier(self.modifier));
744
745 if !self.title.is_empty() {
746 let title: Span<'static> = Span::styled(
747 self.title.clone(),
748 Style::default().add_modifier(self.title_modifier),
749 );
750
751 ret = ret.title(title)
752 };
753
754 if !self.is_empty() {
755 ret = ret
756 .borders(self.sides())
757 .border_type(self.r#type.unwrap_or_default())
758 .border_style(ratatui::style::Style::default().fg(self.color))
759 }
760
761 ret
762 }
763
764 pub fn is_empty(&self) -> bool {
765 self.sides() == Borders::NONE
766 }
767
768 pub fn height(&self) -> u16 {
769 let mut height = 0;
770 height += 2 * !self.is_empty() as u16;
771 height += self.padding.top + self.padding.bottom;
772 height += (!self.title.is_empty() as u16).saturating_sub(!self.is_empty() as u16);
773
774 height
775 }
776
777 pub fn width(&self) -> u16 {
778 let mut width = 0;
779 width += 2 * !self.is_empty() as u16;
780 width += self.padding.left + self.padding.right;
781
782 width
783 }
784
785 pub fn left(&self) -> u16 {
786 let mut width = 0;
787 width += !self.is_empty() as u16;
788 width += self.padding.left;
789
790 width
791 }
792
793 pub fn top(&self) -> u16 {
794 let mut height = 0;
795 height += !self.is_empty() as u16;
796 height += self.padding.top;
797 height += (!self.title.is_empty() as u16).saturating_sub(!self.is_empty() as u16);
798
799 height
800 }
801}
802
803#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
805#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
806pub struct TerminalLayoutSettings {
807 #[partial(alias = "p")]
809 pub percentage: Percentage,
810 pub min: u16,
811 pub max: u16, }
813
814impl Default for TerminalLayoutSettings {
815 fn default() -> Self {
816 Self {
817 percentage: Percentage::new(50),
818 min: 10,
819 max: 120,
820 }
821 }
822}
823
824#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
825#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
826pub struct PreviewSetting {
827 #[serde(flatten)]
828 #[partial(recurse)]
829 pub layout: PreviewLayout,
830 #[partial(recurse)]
831 pub border: Option<BorderSetting>,
832 #[serde(default, alias = "cmd", alias = "x")]
833 pub command: String,
834}
835
836#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
837#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
838pub struct PreviewLayout {
839 pub side: Side,
840 #[serde(alias = "p")]
842 pub percentage: Percentage,
844 pub min: i16,
845 pub max: i16,
846}
847
848impl Default for PreviewLayout {
849 fn default() -> Self {
850 Self {
851 side: Side::Right,
852 percentage: Percentage::new(60),
853 min: 30,
854 max: 120,
855 }
856 }
857}
858
859use crate::utils::serde::bounded_usize;
860#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
861#[serde(default, deny_unknown_fields)]
862#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
863pub struct ColumnsConfig {
864 #[partial(alias = "s")]
866 pub split: Split,
867 #[partial(alias = "n")]
869 pub names: Vec<ColumnSetting>,
870 #[serde(deserialize_with = "bounded_usize::<_, 1, {crate::MAX_SPLITS}>")]
872 #[partial(alias = "mc")]
873 max_columns: usize,
874}
875
876impl ColumnsConfig {
877 pub fn max_cols(&self) -> usize {
878 self.max_columns.min(MAX_SPLITS).max(1)
879 }
880}
881
882impl Default for ColumnsConfig {
883 fn default() -> Self {
884 Self {
885 split: Default::default(),
886 names: Default::default(),
887 max_columns: 6,
888 }
889 }
890}
891
892#[derive(Debug, Clone, PartialEq)]
894pub struct NucleoMatcherConfig(pub nucleo::Config);
895
896impl Default for NucleoMatcherConfig {
897 fn default() -> Self {
898 Self(nucleo::Config::DEFAULT)
899 }
900}
901
902#[derive(Debug, Clone, Serialize, Deserialize)]
903#[serde(default)]
904#[derive(Default)]
905struct MatcherConfigHelper {
906 pub normalize: Option<bool>,
907 pub ignore_case: Option<bool>,
908 pub prefer_prefix: Option<bool>,
909}
910
911impl serde::Serialize for NucleoMatcherConfig {
912 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
913 where
914 S: serde::Serializer,
915 {
916 let helper = MatcherConfigHelper {
917 normalize: Some(self.0.normalize),
918 ignore_case: Some(self.0.ignore_case),
919 prefer_prefix: Some(self.0.prefer_prefix),
920 };
921 helper.serialize(serializer)
922 }
923}
924
925impl<'de> Deserialize<'de> for NucleoMatcherConfig {
926 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
927 where
928 D: serde::Deserializer<'de>,
929 {
930 let helper = MatcherConfigHelper::deserialize(deserializer)?;
931 let mut config = nucleo::Config::DEFAULT;
932
933 if let Some(norm) = helper.normalize {
934 config.normalize = norm;
935 }
936 if let Some(ic) = helper.ignore_case {
937 config.ignore_case = ic;
938 }
939 if let Some(pp) = helper.prefer_prefix {
940 config.prefer_prefix = pp;
941 }
942
943 Ok(NucleoMatcherConfig(config))
944 }
945}