use serde::Serialize;
use crate::collection::{ClusterConfig, CollectionManager, CollectionManagerConfig};
use crate::error::Result;
use crate::types::*;
#[derive(Debug, Clone)]
pub struct ProjectManagerConfig {
pub project_id: String,
pub api_key: String,
pub cluster: Option<ClusterConfig>,
pub auth_jwt_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Default)]
pub struct CloudSearchParams {
pub term: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub mode: Option<SearchMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub offset: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub properties: Option<Vec<String>>,
#[serde(rename = "where", skip_serializing_if = "Option::is_none")]
pub where_clause: Option<AnyObject>,
#[serde(skip_serializing_if = "Option::is_none")]
pub facets: Option<AnyObject>,
pub datasources: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub exact: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub threshold: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tolerance: Option<u32>,
#[serde(rename = "userID", skip_serializing_if = "Option::is_none")]
pub user_id: Option<String>,
}
#[derive(Debug, Clone)]
pub struct DataSourceNamespace {
index: crate::collection::Index,
}
impl DataSourceNamespace {
pub(crate) fn new(index: crate::collection::Index) -> Self {
Self { index }
}
pub async fn reindex(&self) -> Result<()> {
self.index.reindex().await
}
pub async fn insert_documents<T>(&self, documents: Vec<T>) -> Result<()>
where
T: serde::Serialize,
{
self.index.insert_documents(documents).await
}
pub async fn delete_documents(&self, document_ids: Vec<String>) -> Result<()> {
self.index.delete_documents(document_ids).await
}
pub async fn upsert_documents<T>(&self, documents: Vec<T>) -> Result<()>
where
T: serde::Serialize,
{
self.index.upsert_documents(documents).await
}
}
#[derive(Debug, Clone)]
pub struct OramaCloud {
client: CollectionManager,
}
impl OramaCloud {
pub async fn new(config: ProjectManagerConfig) -> Result<Self> {
let mut collection_config = CollectionManagerConfig::new(config.project_id, config.api_key);
if let Some(cluster) = config.cluster {
collection_config = collection_config.with_cluster(cluster);
}
if let Some(auth_jwt_url) = config.auth_jwt_url {
collection_config = collection_config.with_auth_jwt_url(auth_jwt_url);
}
let client = CollectionManager::new(collection_config).await?;
Ok(Self { client })
}
pub async fn search<T>(&self, params: &CloudSearchParams) -> Result<SearchResult<T>>
where
T: for<'de> serde::Deserialize<'de>,
{
let search_params = SearchParams {
term: params.term.clone(),
mode: params.mode.clone(),
limit: params.limit,
offset: params.offset,
properties: params.properties.clone(),
where_clause: params.where_clause.clone(),
facets: params.facets.clone(),
indexes: Some(params.datasources.clone()), datasource_ids: None,
exact: params.exact,
threshold: params.threshold,
tolerance: params.tolerance,
user_id: params.user_id.clone(),
};
self.client.search(&search_params).await
}
pub fn data_source(&self, id: String) -> DataSourceNamespace {
let index = self.client.index.set(id);
DataSourceNamespace::new(index)
}
pub fn ai(&self) -> &crate::collection::AiNamespace {
&self.client.ai
}
pub fn collections(&self) -> &crate::collection::CollectionsNamespace {
&self.client.collections
}
pub fn index(&self) -> &crate::collection::IndexNamespace {
&self.client.index
}
pub fn hooks(&self) -> &crate::collection::HooksNamespace {
&self.client.hooks
}
pub fn system_prompts(&self) -> &crate::collection::SystemPromptsNamespace {
&self.client.system_prompts
}
pub fn tools(&self) -> &crate::collection::ToolsNamespace {
&self.client.tools
}
}
impl ProjectManagerConfig {
pub fn new<S: Into<String>>(project_id: S, api_key: S) -> Self {
Self {
project_id: project_id.into(),
api_key: api_key.into(),
cluster: None,
auth_jwt_url: None,
}
}
pub fn with_cluster(mut self, cluster: ClusterConfig) -> Self {
self.cluster = Some(cluster);
self
}
pub fn with_auth_jwt_url<S: Into<String>>(mut self, url: S) -> Self {
self.auth_jwt_url = Some(url.into());
self
}
}
impl CloudSearchParams {
pub fn new<S: Into<String>>(term: S, datasources: Vec<String>) -> Self {
Self {
term: term.into(),
datasources,
..Default::default()
}
}
pub fn with_mode(mut self, mode: SearchMode) -> Self {
self.mode = Some(mode);
self
}
pub fn with_limit(mut self, limit: u32) -> Self {
self.limit = Some(limit);
self
}
pub fn with_offset(mut self, offset: u32) -> Self {
self.offset = Some(offset);
self
}
pub fn with_properties(mut self, properties: Vec<String>) -> Self {
self.properties = Some(properties);
self
}
pub fn with_where(mut self, where_clause: AnyObject) -> Self {
self.where_clause = Some(where_clause);
self
}
pub fn with_facets(mut self, facets: AnyObject) -> Self {
self.facets = Some(facets);
self
}
pub fn with_exact(mut self, exact: bool) -> Self {
self.exact = Some(exact);
self
}
pub fn with_threshold(mut self, threshold: f64) -> Self {
self.threshold = Some(threshold);
self
}
pub fn with_tolerance(mut self, tolerance: u32) -> Self {
self.tolerance = Some(tolerance);
self
}
pub fn with_user_id<S: Into<String>>(mut self, user_id: S) -> Self {
self.user_id = Some(user_id.into());
self
}
}