1#[derive(
11 serde::Serialize,
12 serde::Deserialize,
13 zerompk::ToMessagePack,
14 zerompk::FromMessagePack,
15 Clone,
16 Debug,
17)]
18pub struct Posting {
19 pub doc_id: String,
20 pub term_freq: u32,
21 pub positions: Vec<u32>,
22}
23
24#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
26pub enum QueryMode {
27 #[default]
29 And,
30 Or,
32}
33
34#[derive(Debug, Clone)]
36pub struct TextSearchResult {
37 pub doc_id: String,
38 pub score: f32,
39 pub fuzzy: bool,
41}
42
43#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct MatchOffset {
46 pub start: usize,
47 pub end: usize,
48 pub term: String,
49}
50
51#[derive(Debug, Clone, Copy)]
53pub struct Bm25Params {
54 pub k1: f32,
56 pub b: f32,
58}
59
60impl Default for Bm25Params {
61 fn default() -> Self {
62 Self { k1: 1.2, b: 0.75 }
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn default_query_mode_is_and() {
72 assert_eq!(QueryMode::default(), QueryMode::And);
73 }
74
75 #[test]
76 fn default_bm25_params() {
77 let p = Bm25Params::default();
78 assert!((p.k1 - 1.2).abs() < f32::EPSILON);
79 assert!((p.b - 0.75).abs() < f32::EPSILON);
80 }
81
82 #[test]
83 fn posting_fields() {
84 let posting = Posting {
85 doc_id: "doc1".into(),
86 term_freq: 3,
87 positions: vec![0, 5, 12],
88 };
89 assert_eq!(posting.doc_id, "doc1");
90 assert_eq!(posting.term_freq, 3);
91 assert_eq!(posting.positions, vec![0, 5, 12]);
92 }
93}