Struct SearchCatalog
pub struct SearchCatalog { /* private fields */ }Expand description
A complete, incremental search catalogue keyed by canonical resource id.
Cloning a catalogue is O(1), so a widget can retain one instance and return a cheap provider handle whenever Ctrl+K opens. Mutations are recorded immediately and indexed in one batch before the next query. Queries are paged by both result count and work budget; result objects are cloned only for the hits in the requested page.
Fields are found by folded substring and ranked by the best weighted
field match (see [tilo_search]). Bodies (SearchRecord::body) are
found after every field hit, and a body source that names locations
reports the segment a match is in. A unique item is found directly in a
corpus of any size; broad queries continue through SearchCursor pages.
Implementations§
§impl SearchCatalog
impl SearchCatalog
pub fn new(name: impl Into<Arc<str>>) -> SearchCatalog
pub fn detached(&self) -> SearchCatalog
pub fn detached(&self) -> SearchCatalog
An independent copy of this catalogue at its current generation. A session can extend the copy without the published catalogue — or any other session sharing it — observing the change.
pub fn replace_all(
&self,
rows: impl IntoIterator<Item = (String, String, SearchResult)>,
) -> Result<(), SearchCatalogError>
pub fn replace_all( &self, rows: impl IntoIterator<Item = (String, String, SearchResult)>, ) -> Result<(), SearchCatalogError>
Replace an immutable snapshot in one generation. This is the bulk
counterpart to Self::upsert: the whole snapshot is indexed in one
build, while later incremental updates retain their existing
semantics.
§Errors
Returns an error for malformed, duplicate, or non-canonical rows, or when catalogue generation/browse identities are exhausted.
pub fn replace_all_records(
&self,
records: impl IntoIterator<Item = SearchRecord>,
) -> Result<(), SearchCatalogError>
pub fn replace_all_records( &self, records: impl IntoIterator<Item = SearchRecord>, ) -> Result<(), SearchCatalogError>
pub fn sync(
&self,
rows: impl IntoIterator<Item = (String, String, SearchResult)>,
) -> Result<bool, SearchCatalogError>
pub fn sync( &self, rows: impl IntoIterator<Item = (String, String, SearchResult)>, ) -> Result<bool, SearchCatalogError>
Self::sync_records for legacy (resource id, searchable text, result) rows, as Self::replace_all takes them.
§Errors
pub fn sync_records(
&self,
records: impl IntoIterator<Item = SearchRecord>,
) -> Result<bool, SearchCatalogError>
pub fn sync_records( &self, records: impl IntoIterator<Item = SearchRecord>, ) -> Result<bool, SearchCatalogError>
Make records, in their order, the whole catalogue, as
Self::replace_all_records would, indexing only the records that
are new, changed or moved, and dropping those absent. Hits and
browsing come in the same order a bulk replacement gives. The
generation advances once if anything changed and not at all
otherwise, so an unchanged snapshot keeps every cursor current.
The catalogue’s write lock is held only to compare and stage the
records; indexing them waits for the next query or
Self::index_bytes, incrementally when few changed.
§Errors
As Self::replace_all_records; the catalogue is then unchanged.
pub fn contains(&self, resource_id: &str) -> bool
pub fn contains(&self, resource_id: &str) -> bool
Whether a canonical resource is currently retained by this catalogue.
pub fn upsert(
&self,
resource_id: impl Into<String>,
searchable_text: impl AsRef<str>,
result: SearchResult,
) -> Result<(), SearchCatalogError>
pub fn upsert( &self, resource_id: impl Into<String>, searchable_text: impl AsRef<str>, result: SearchResult, ) -> Result<(), SearchCatalogError>
Insert or replace one durable resource. searchable_text may combine
title, metadata and body; result is materialised only when it is a
hit on a requested page.
§Errors
Returns SearchCatalogError when the stable id is empty, the result
is legacy/opaque, or its canonical action addresses another resource.
pub fn upsert_record(
&self,
record: SearchRecord,
) -> Result<(), SearchCatalogError>
pub fn upsert_record( &self, record: SearchRecord, ) -> Result<(), SearchCatalogError>
pub fn stats(&self) -> SearchCatalogStats
pub fn index_bytes(&self) -> u64
pub fn index_bytes(&self) -> u64
Bytes the catalogue’s index occupies, once every mutation is indexed.
pub fn cursor_is_current(&self, cursor: &SearchCursor) -> bool
pub fn cursor_is_current(&self, cursor: &SearchCursor) -> bool
Whether a prior cursor belongs to this exact retained-index generation. The pull directory must turn a mismatch into a stale cursor response, never reinterpret it as an exhausted result set.
pub fn query_page(
&self,
query: &str,
cursor: Option<&SearchCursor>,
work_budget: usize,
result_limit: usize,
) -> SearchPage
pub fn query_page( &self, query: &str, cursor: Option<&SearchCursor>, work_budget: usize, result_limit: usize, ) -> SearchPage
Query one deterministic page. Both budgets are hard ceilings. Continue
with the returned cursor when next is set.
Trait Implementations§
§impl CatalogSearchProvider for SearchCatalog
impl CatalogSearchProvider for SearchCatalog
§fn provider_name(&self) -> &str
fn provider_name(&self) -> &str
SearchProvider::name.§fn catalog(&self) -> Option<SearchCatalog>
fn catalog(&self) -> Option<SearchCatalog>
None while none is published (a
provider with no catalogue reports no generation and empty pages). Read more§const RESULT_LIMIT: usize = DEFAULT_SEARCH_RESULT_LIMIT
const RESULT_LIMIT: usize = DEFAULT_SEARCH_RESULT_LIMIT
search and search_limited return. Providers whose
palette section shows fewer rows lower it.§fn limited_work_budget(&self, _limit: usize) -> usize
fn limited_work_budget(&self, _limit: usize) -> usize
search_limited(limit)
call. The default inspects up to DEFAULT_SEARCH_CANDIDATE_LIMIT
candidates to fill limit results; a provider may instead spend no
more inspections than results it asked for. query_page caps either
at the shared ceiling.§fn catalog_query<'q>(&self, query: &'q str) -> Cow<'q, str>
fn catalog_query<'q>(&self, query: &'q str) -> Cow<'q, str>
§fn resolve_action_address(&self, _address: &ActionAddress) -> Option<Resource>
fn resolve_action_address(&self, _address: &ActionAddress) -> Option<Resource>
§fn search_scopes(&self) -> Vec<ScopeDecl>
fn search_scopes(&self) -> Vec<ScopeDecl>
SearchProvider::search_scopes: the parts of the app this
catalogue’s hits can be narrowed to.§fn admits(&self, _hit: &SearchResult, _query: &SearchQuery) -> bool
fn admits(&self, _hit: &SearchResult, _query: &SearchQuery) -> bool
hit passes query’s facet filters. The catalogue matches
text only; a provider with facets checks the hit’s values here
(query.admits("language", &[..])). The default admits every hit.§impl Clone for SearchCatalog
impl Clone for SearchCatalog
§fn clone(&self) -> SearchCatalog
fn clone(&self) -> SearchCatalog
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for SearchCatalog
impl RefUnwindSafe for SearchCatalog
impl Send for SearchCatalog
impl Sync for SearchCatalog
impl Unpin for SearchCatalog
impl UnsafeUnpin for SearchCatalog
impl UnwindSafe for SearchCatalog
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> SearchProvider for Twhere
T: CatalogSearchProvider,
impl<T> SearchProvider for Twhere
T: CatalogSearchProvider,
§fn name(&self) -> &str
fn name(&self) -> &str
SearchResult::kind.§fn action_directory_generation(&self) -> Option<u64>
fn action_directory_generation(&self) -> Option<u64>
None means the provider has not proved that a continuation cursor is
safe across mutation, so remote directory discovery must omit it
rather than silently advertise mutable rows as revision-stable.
Providers backed by SearchCatalog should return
Some(catalog.stats().generation).§fn action_directory_cursor_is_current(&self, cursor: &SearchCursor) -> bool
fn action_directory_cursor_is_current(&self, cursor: &SearchCursor) -> bool
§fn search(&self, query: &str) -> Vec<SearchResult>
fn search(&self, query: &str) -> Vec<SearchResult>
query. An empty query conventionally
returns a provider’s “browse” set (recents / favourites / all), or an
empty vec if browsing makes no sense for the source.§fn search_limited(&self, query: &str, limit: usize) -> Vec<SearchResult>
fn search_limited(&self, query: &str, limit: usize) -> Vec<SearchResult>
limit is reached. The fallback exists
only for tiny/test providers outside apps/; the repository contract
checker rejects app implementations that inherit it.§fn search_page(
&self,
query: &SearchQuery,
cursor: Option<&SearchCursor>,
work_budget: usize,
result_limit: usize,
) -> SearchPage
fn search_page( &self, query: &SearchQuery, cursor: Option<&SearchCursor>, work_budget: usize, result_limit: usize, ) -> SearchPage
§fn facets(&self) -> Vec<Facet>
fn facets(&self) -> Vec<Facet>
key:value tokens for them into
SearchQuery::filters.§fn search_scopes(&self) -> Vec<ScopeDecl>
fn search_scopes(&self) -> Vec<ScopeDecl>
ScopeDecl). An unscoped palette offers each as a
“Search in” row that narrows the search to it.§fn resolve_action_resource(&self, address: &ActionAddress) -> Option<Resource>
fn resolve_action_resource(&self, address: &ActionAddress) -> Option<Resource>
§fn action_directory_invocation_domain(&self) -> ActionDirectoryInvocationDomain
fn action_directory_invocation_domain(&self) -> ActionDirectoryInvocationDomain
§fn poll_page(&self, _token: &PendingToken) -> PagePoll
fn poll_page(&self, _token: &PendingToken) -> PagePoll
SearchPage::pending token stands for, once its source
has answered. Called on later frames, never in a loop; return
PagePoll::Pending until the answer is in. A token the provider no
longer knows (the query moved on) answers an empty ready page.