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 pub sort_threshold: u32,
46 #[partial(alias = "r")]
50 pub raw: bool,
51 pub track: bool,
53 pub reverse: bool, }
56
57#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
60#[serde(default, deny_unknown_fields)]
61#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
62pub struct StartConfig {
63 #[serde(deserialize_with = "escaped_opt_char")]
64 #[partial(alias = "is")]
65 pub input_separator: Option<char>,
66 #[serde(deserialize_with = "escaped_opt_string")]
67 #[partial(alias = "os")]
68 pub output_separator: Option<String>,
69
70 #[partial(alias = "ot")]
72 #[serde(alias = "output")]
73 pub output_template: Option<String>,
74
75 #[partial(alias = "cmd", alias = "x")]
77 pub command: String,
78 #[partial(alias = "ax")]
80 pub additional_commands: Vec<String>,
81 pub sync: bool,
82
83 #[partial(alias = "a")]
85 pub ansi: bool,
86 #[partial(alias = "t")]
88 pub trim: bool,
89}
90
91#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
93#[serde(default, deny_unknown_fields)]
94#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
95pub struct ExitConfig {
96 pub select_1: bool,
98 pub allow_empty: bool,
100 pub abort_empty: bool,
102 pub last_key_path: Option<std::path::PathBuf>,
105}
106
107#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
109#[serde(default, deny_unknown_fields)]
110#[partial(recurse, path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
111pub struct RenderConfig {
112 pub ui: UiConfig,
114 #[partial(alias = "i")]
116 pub input: InputConfig,
117 #[partial(alias = "r")]
119 pub results: ResultsConfig,
120
121 pub status: StatusConfig,
123 #[partial(alias = "p")]
125 pub preview: PreviewConfig,
126 #[partial(alias = "f")]
127 pub footer: DisplayConfig,
128 #[partial(alias = "h")]
129 pub header: DisplayConfig,
130}
131
132impl RenderConfig {
133 pub fn tick_rate(&self) -> u8 {
134 self.ui.tick_rate
135 }
136}
137
138#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
140#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141#[serde(default, deny_unknown_fields)]
142pub struct TerminalConfig {
143 pub stream: IoStream, pub restore_fullscreen: bool,
145 pub redraw_on_resize: bool,
146 pub extended_keys: bool,
148 #[serde(with = "serde_duration_ms")]
149 pub sleep_ms: std::time::Duration, #[serde(flatten)]
151 #[partial(recurse)]
152 pub layout: Option<TerminalLayoutSettings>, pub clear_on_exit: bool,
154 pub move_up_on_exit: bool,
156}
157
158impl Default for TerminalConfig {
159 fn default() -> Self {
160 Self {
161 stream: IoStream::default(),
162 restore_fullscreen: true,
163 redraw_on_resize: bool::default(),
164 sleep_ms: std::time::Duration::default(),
165 layout: Option::default(),
166 extended_keys: true,
167 clear_on_exit: true,
168 move_up_on_exit: false,
169 }
170 }
171}
172
173#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
175#[serde(default, deny_unknown_fields)]
176#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
177pub struct UiConfig {
178 #[partial(recurse)]
179 pub border: BorderSetting,
180 pub tick_rate: u8, }
182
183impl Default for UiConfig {
184 fn default() -> Self {
185 Self {
186 border: Default::default(),
187 tick_rate: 60,
188 }
189 }
190}
191
192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
194#[serde(default, deny_unknown_fields)]
195#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
196pub struct InputConfig {
197 #[partial(recurse)]
198 pub border: BorderSetting,
199
200 #[serde(deserialize_with = "camelcase_normalized")]
202 pub fg: Color,
203 pub bg: Color,
204 pub modifier: Modifier,
206
207 #[serde(deserialize_with = "camelcase_normalized")]
208 pub prompt_fg: Color,
209 pub prompt_bg: Color,
210 pub prompt_modifier: Modifier,
212
213 #[serde(deserialize_with = "deserialize_string_or_char_as_double_width")]
215 pub prompt: String,
216 pub cursor: CursorSetting,
218
219 #[partial(alias = "i")]
221 pub initial: String,
222
223 pub scroll_padding: bool,
225}
226
227impl Default for InputConfig {
228 fn default() -> Self {
229 Self {
230 border: Default::default(),
231 fg: Default::default(),
232 bg: Default::default(),
233 modifier: Default::default(),
234 prompt_fg: Default::default(),
235 prompt_bg: Default::default(),
236 prompt_modifier: Default::default(),
237 prompt: "> ".to_string(),
238 cursor: Default::default(),
239 initial: Default::default(),
240
241 scroll_padding: true,
242 }
243 }
244}
245
246impl InputConfig {
247 pub fn text_style(&self) -> Style {
248 Style::default()
249 .fg(self.fg)
250 .bg(self.bg)
251 .remove_modifier(Modifier::all())
252 .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: 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: Default::default(),
415 inactive_bg: Default::default(),
416
417 inactive_current_fg: Color::DarkGray,
418 inactive_current_modifier: Default::default(),
419 inactive_current_bg: Color::Black,
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: RowConnectionStyle::Capped,
428
429 scroll_wrap: true,
430 scroll_padding: 2,
431 reverse: Default::default(),
432
433 wrap: Default::default(),
434 min_wrap_width: 4,
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: 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: 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: 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: 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, deny_unknown_fields)]
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 #[serde(alias = "scroll")]
577 #[partial(recurse)]
578 #[partial(alias = "i")]
579 pub initial: PreviewInitialSetting,
580 #[partial(alias = "c")]
582 #[serde(alias = "cycle")]
583 pub scroll_wrap: bool,
584 pub wrap: bool,
585 pub show: ShowCondition,
588
589 pub reevaluate_show_on_resize: bool,
590}
591
592impl Default for PreviewConfig {
593 fn default() -> Self {
594 PreviewConfig {
595 border: BorderSetting {
596 padding: Padding(ratatui::widgets::Padding::left(2)),
597 ..Default::default()
598 },
599 initial: Default::default(),
600 layout: Default::default(),
601 scroll_wrap: true,
602 wrap: Default::default(),
603 show: Default::default(),
604 reevaluate_show_on_resize: false,
605 }
606 }
607}
608
609#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
611#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
612#[serde(default, deny_unknown_fields)]
613pub struct PreviewInitialSetting {
614 pub index: Option<StringValue>,
617 #[partial(alias = "o")]
619 pub offset: isize,
620 #[partial(alias = "p")]
622 pub percentage: Percentage,
623 #[partial(alias = "h")]
625 pub header_lines: usize,
626}
627
628impl Default for PreviewInitialSetting {
629 fn default() -> Self {
630 Self {
631 index: Default::default(),
632 offset: -1,
633 percentage: Default::default(),
634 header_lines: Default::default(),
635 }
636 }
637}
638
639#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
640#[serde(default, deny_unknown_fields)]
641pub struct PreviewerConfig {
642 pub try_lossy: bool,
643
644 pub cache: u8,
646
647 pub help_colors: HelpColorConfig,
648}
649
650#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
652pub struct HelpColorConfig {
653 #[serde(deserialize_with = "camelcase_normalized")]
654 pub section: Color,
655 #[serde(deserialize_with = "camelcase_normalized")]
656 pub key: Color,
657 #[serde(deserialize_with = "camelcase_normalized")]
658 pub value: Color,
659}
660
661impl Default for HelpColorConfig {
662 fn default() -> Self {
663 Self {
664 section: Color::Blue,
665 key: Color::Green,
666 value: Color::White,
667 }
668 }
669}
670
671#[derive(Default, Debug, Clone, PartialEq, Deserialize, Serialize)]
674#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
675#[serde(default, deny_unknown_fields)]
676pub struct BorderSetting {
677 #[serde(deserialize_with = "camelcase_normalized_option")]
678 pub r#type: Option<BorderType>,
679 #[serde(deserialize_with = "camelcase_normalized")]
680 pub color: Color,
681 pub sides: Option<Borders>,
690 pub padding: Padding,
698 pub title: String,
699 pub title_modifier: Modifier,
701 pub modifier: Modifier,
702 #[serde(deserialize_with = "camelcase_normalized")]
703 pub bg: Color,
704}
705
706impl BorderSetting {
707 pub fn as_block(&self) -> ratatui::widgets::Block<'_> {
708 let mut ret = ratatui::widgets::Block::default()
709 .padding(self.padding.0)
710 .style(Style::default().bg(self.bg).add_modifier(self.modifier));
711
712 if !self.title.is_empty() {
713 let title = Span::styled(
714 &self.title,
715 Style::default().add_modifier(self.title_modifier),
716 );
717
718 ret = ret.title(title)
719 };
720
721 if !self.is_empty() {
722 ret = ret
723 .borders(self.sides())
724 .border_type(self.r#type.unwrap_or_default())
725 .border_style(ratatui::style::Style::default().fg(self.color))
726 }
727
728 ret
729 }
730
731 pub fn sides(&self) -> Borders {
732 if let Some(s) = self.sides {
733 s
734 } else if self.color != Default::default() || self.r#type != Default::default() {
735 Borders::ALL
736 } else {
737 Borders::NONE
738 }
739 }
740
741 pub fn as_static_block(&self) -> ratatui::widgets::Block<'static> {
742 let mut ret = ratatui::widgets::Block::default()
743 .padding(self.padding.0)
744 .style(Style::default().bg(self.bg).add_modifier(self.modifier));
745
746 if !self.title.is_empty() {
747 let title: Span<'static> = Span::styled(
748 self.title.clone(),
749 Style::default().add_modifier(self.title_modifier),
750 );
751
752 ret = ret.title(title)
753 };
754
755 if !self.is_empty() {
756 ret = ret
757 .borders(self.sides())
758 .border_type(self.r#type.unwrap_or_default())
759 .border_style(ratatui::style::Style::default().fg(self.color))
760 }
761
762 ret
763 }
764
765 pub fn is_empty(&self) -> bool {
766 self.sides() == Borders::NONE
767 }
768
769 pub fn height(&self) -> u16 {
770 let mut height = 0;
771 height += 2 * !self.is_empty() as u16;
772 height += self.padding.top + self.padding.bottom;
773 height += (!self.title.is_empty() as u16).saturating_sub(!self.is_empty() as u16);
774
775 height
776 }
777
778 pub fn width(&self) -> u16 {
779 let mut width = 0;
780 width += 2 * !self.is_empty() as u16;
781 width += self.padding.left + self.padding.right;
782
783 width
784 }
785
786 pub fn left(&self) -> u16 {
787 let mut width = 0;
788 width += !self.is_empty() as u16;
789 width += self.padding.left;
790
791 width
792 }
793
794 pub fn top(&self) -> u16 {
795 let mut height = 0;
796 height += !self.is_empty() as u16;
797 height += self.padding.top;
798 height += (!self.title.is_empty() as u16).saturating_sub(!self.is_empty() as u16);
799
800 height
801 }
802}
803
804#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
806#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
807pub struct TerminalLayoutSettings {
808 #[partial(alias = "p")]
810 pub percentage: Percentage,
811 pub min: u16,
812 pub max: u16, }
814
815impl Default for TerminalLayoutSettings {
816 fn default() -> Self {
817 Self {
818 percentage: Percentage::new(50),
819 min: 10,
820 max: 120,
821 }
822 }
823}
824
825#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
826#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
827#[serde(default)]
828pub struct PreviewSetting {
829 #[serde(flatten)]
830 #[partial(recurse)]
831 pub layout: PreviewLayout,
832 #[partial(recurse)]
833 pub border: Option<BorderSetting>,
834 #[serde(default, alias = "cmd", alias = "x")]
835 pub command: String,
836}
837
838#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
839#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
840#[serde(default)]
841pub struct PreviewLayout {
842 pub side: Side,
843 #[serde(alias = "p")]
845 pub percentage: Percentage,
847 pub min: i16,
848 pub max: i16,
849}
850
851impl Default for PreviewLayout {
852 fn default() -> Self {
853 Self {
854 side: Side::Right,
855 percentage: Percentage::new(60),
856 min: 15,
857 max: 120,
858 }
859 }
860}
861
862use crate::utils::serde::bounded_usize;
863#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
864#[serde(default, deny_unknown_fields)]
865#[partial(path, derive(Debug, Clone, PartialEq, Deserialize, Serialize))]
866pub struct ColumnsConfig {
867 #[partial(alias = "s")]
869 pub split: Split,
870 #[partial(alias = "n")]
872 pub names: Vec<ColumnSetting>,
873 #[serde(deserialize_with = "bounded_usize::<_, 1, {crate::MAX_SPLITS}>")]
875 #[partial(alias = "mc")]
876 max: usize,
877 #[partial(alias = "i")]
878 pub default: Option<StringValue>,
879 pub names_from_zero: bool,
881}
882
883impl ColumnsConfig {
884 pub fn max_cols(&self) -> usize {
885 self.max.min(MAX_SPLITS).max(1)
886 }
887}
888
889impl Default for ColumnsConfig {
890 fn default() -> Self {
891 Self {
892 split: Default::default(),
893 names: Default::default(),
894 max: 6,
895 default: None,
896 names_from_zero: false,
897 }
898 }
899}
900
901#[derive(Debug, Clone, PartialEq)]
903pub struct NucleoMatcherConfig(pub nucleo::Config);
904
905impl Default for NucleoMatcherConfig {
906 fn default() -> Self {
907 Self(nucleo::Config::DEFAULT)
908 }
909}
910
911#[derive(Debug, Clone, Serialize, Deserialize)]
912#[serde(default)]
913#[derive(Default)]
914struct MatcherConfigHelper {
915 pub normalize: Option<bool>,
916 pub ignore_case: Option<bool>,
917 pub prefer_prefix: Option<bool>,
918}
919
920impl serde::Serialize for NucleoMatcherConfig {
921 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
922 where
923 S: serde::Serializer,
924 {
925 let helper = MatcherConfigHelper {
926 normalize: Some(self.0.normalize),
927 ignore_case: Some(self.0.ignore_case),
928 prefer_prefix: Some(self.0.prefer_prefix),
929 };
930 helper.serialize(serializer)
931 }
932}
933
934impl<'de> Deserialize<'de> for NucleoMatcherConfig {
935 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
936 where
937 D: serde::Deserializer<'de>,
938 {
939 let helper = MatcherConfigHelper::deserialize(deserializer)?;
940 let mut config = nucleo::Config::DEFAULT;
941
942 if let Some(norm) = helper.normalize {
943 config.normalize = norm;
944 }
945 if let Some(ic) = helper.ignore_case {
946 config.ignore_case = ic;
947 }
948 if let Some(pp) = helper.prefer_prefix {
949 config.prefer_prefix = pp;
950 }
951
952 Ok(NucleoMatcherConfig(config))
953 }
954}