1pub mod config;
2pub mod durability;
3pub mod error;
4pub mod model;
5pub mod wasi_compat;
6
7use crate::model::{
8 CreateIndexOptions, Doc, DocumentId, IndexName, Schema, SearchError, SearchHit, SearchQuery,
9 SearchResults, SearchStream,
10};
11use std::cell::RefCell;
12use std::str::FromStr;
13
14pub trait SearchStreamInterface: 'static {
15 fn as_any(&self) -> &dyn std::any::Any;
16 fn as_any_mut(&mut self) -> &mut dyn std::any::Any;
17 fn get_next(&self) -> Option<Vec<SearchHit>>;
18 fn blocking_get_next(&self) -> Vec<SearchHit>;
19}
20
21pub trait SearchProvider {
22 type SearchStream: SearchStreamInterface;
23
24 type ProviderConfig: Clone + 'static;
29
30 fn create_index(
31 provider_config: Self::ProviderConfig,
32 options: CreateIndexOptions,
33 ) -> Result<(), SearchError>;
34 fn delete_index(
35 provider_config: Self::ProviderConfig,
36 name: IndexName,
37 ) -> Result<(), SearchError>;
38 fn list_indexes(provider_config: Self::ProviderConfig) -> Result<Vec<IndexName>, SearchError>;
39 fn upsert(
40 provider_config: Self::ProviderConfig,
41 index: IndexName,
42 doc: Doc,
43 ) -> Result<(), SearchError>;
44 fn upsert_many(
45 provider_config: Self::ProviderConfig,
46 index: IndexName,
47 docs: Vec<Doc>,
48 ) -> Result<(), SearchError>;
49 fn delete(
50 provider_config: Self::ProviderConfig,
51 index: IndexName,
52 id: DocumentId,
53 ) -> Result<(), SearchError>;
54 fn delete_many(
55 provider_config: Self::ProviderConfig,
56 index: IndexName,
57 ids: Vec<DocumentId>,
58 ) -> Result<(), SearchError>;
59 fn get(
60 provider_config: Self::ProviderConfig,
61 index: IndexName,
62 id: DocumentId,
63 ) -> Result<Option<Doc>, SearchError>;
64 fn search(
65 provider_config: Self::ProviderConfig,
66 index: IndexName,
67 query: SearchQuery,
68 ) -> Result<SearchResults, SearchError>;
69 fn stream_search(
70 provider_config: Self::ProviderConfig,
71 index: IndexName,
72 query: SearchQuery,
73 ) -> Result<SearchStream, SearchError>;
74 fn get_schema(
75 provider_config: Self::ProviderConfig,
76 index: IndexName,
77 ) -> Result<Schema, SearchError>;
78 fn update_schema(
79 provider_config: Self::ProviderConfig,
80 index: IndexName,
81 schema: Schema,
82 ) -> Result<(), SearchError>;
83}
84
85impl<'a> From<&'a SearchError> for SearchError {
86 fn from(value: &'a SearchError) -> Self {
87 value.clone()
88 }
89}
90
91struct LoggingState {
92 logging_initialized: bool,
93}
94
95impl LoggingState {
96 fn init(&mut self) {
97 if !self.logging_initialized {
98 let _ = wasi_logger::Logger::install();
99 let max_level: log::LevelFilter = log::LevelFilter::from_str(
100 &std::env::var("SEARCH_PROVIDER_LOG_LEVEL").unwrap_or_default(),
101 )
102 .unwrap_or(log::LevelFilter::Info);
103 log::set_max_level(max_level);
104 self.logging_initialized = true;
105 }
106 }
107}
108
109thread_local! {
110 static LOGGING_STATE: RefCell<LoggingState> = const { RefCell::new(LoggingState {
111 logging_initialized: false,
112 }) };
113}
114
115pub fn init_logging() {
116 LOGGING_STATE.with_borrow_mut(|state| state.init());
117}