use crate::{ EntryType, StringMatcher };
#[derive( Debug, Clone )]
pub struct SearchFilter
{
pub query : String,
pub case_sensitive : bool,
pub match_entry_type : Option< EntryType >,
}
impl SearchFilter
{
#[inline]
pub fn new( query : impl Into< String > ) -> Self
{
Self
{
query : query.into(),
case_sensitive : false,
match_entry_type : None,
}
}
#[must_use]
#[inline]
pub fn case_sensitive( mut self, value : bool ) -> Self
{
self.case_sensitive = value;
self
}
#[must_use]
#[inline]
pub fn match_entry_type( mut self, entry_type : EntryType ) -> Self
{
self.match_entry_type = Some( entry_type );
self
}
#[must_use]
#[inline]
pub fn matches_text( &self, text : &str ) -> bool
{
if self.case_sensitive
{
text.contains( &self.query )
}
else
{
let matcher = StringMatcher::new( &self.query );
matcher.matches( text )
}
}
}
#[derive( Debug, Clone )]
pub struct SearchMatch
{
pub entry_index : usize,
pub entry_type : EntryType,
pub line_number : usize,
pub excerpt : String,
pub full_line : String,
}
impl SearchMatch
{
#[must_use]
#[inline]
pub fn new
(
entry_index : usize,
entry_type : EntryType,
line_number : usize,
full_line : String,
)
-> Self
{
let excerpt = if full_line.chars().count() > 150
{
let char_count = full_line.chars().count();
let start_char = char_count.saturating_sub( 100 ) / 2;
let end_char = start_char + 100;
let excerpt_str : String = full_line
.chars()
.skip( start_char )
.take( end_char - start_char )
.collect();
format!( "...{excerpt_str}..." )
}
else
{
full_line.clone()
};
Self
{
entry_index,
entry_type,
line_number,
excerpt,
full_line,
}
}
#[must_use]
#[inline]
pub fn entry_index( &self ) -> usize
{
self.entry_index
}
#[must_use]
#[inline]
pub fn entry_type( &self ) -> EntryType
{
self.entry_type
}
#[must_use]
#[inline]
pub fn line_number( &self ) -> usize
{
self.line_number
}
#[must_use]
#[inline]
pub fn excerpt( &self ) -> &str
{
&self.excerpt
}
#[must_use]
#[inline]
pub fn full_line( &self ) -> &str
{
&self.full_line
}
}