use serde::{Deserialize, Serialize};
use strum::AsRefStr;
use time::OffsetDateTime;
use crate::common::serde::{
deserialize_optional_string_to_i64, deserialize_string_to_i64, mime_as_string,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FileSearchStore {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(with = "time::serde::rfc3339")]
pub create_time: OffsetDateTime,
#[serde(with = "time::serde::rfc3339")]
pub update_time: OffsetDateTime,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_optional_string_to_i64"
)]
pub active_documents_count: Option<i64>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_optional_string_to_i64"
)]
pub pending_documents_count: Option<i64>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_optional_string_to_i64"
)]
pub failed_documents_count: Option<i64>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "deserialize_optional_string_to_i64"
)]
pub size_bytes: Option<i64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateFileSearchStoreRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Document {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_metadata: Option<Vec<CustomMetadata>>,
#[serde(with = "time::serde::rfc3339")]
pub update_time: OffsetDateTime,
#[serde(with = "time::serde::rfc3339")]
pub create_time: OffsetDateTime,
pub state: DocumentState,
#[serde(deserialize_with = "deserialize_string_to_i64")]
pub size_bytes: i64,
#[serde(with = "mime_as_string")]
pub mime_type: mime::Mime,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, AsRefStr)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[strum(serialize_all = "SCREAMING_SNAKE_CASE")]
pub enum DocumentState {
StateUnspecified,
StatePending,
StateActive,
StateFailed,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CustomMetadata {
pub key: String,
#[serde(flatten)]
pub value: CustomMetadataValue,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CustomMetadataValue {
StringValue { string_value: String },
StringListValue { string_list_value: StringList },
NumericValue { numeric_value: f64 },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StringList {
pub values: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ChunkingConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub white_space_config: Option<WhiteSpaceConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WhiteSpaceConfig {
pub max_tokens_per_chunk: u32,
pub max_overlap_tokens: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Operation {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<serde_json::Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub done: Option<bool>,
#[serde(flatten)]
pub result: Option<OperationResult>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum OperationResult {
Error { error: Status },
Response { response: serde_json::Value },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Status {
pub code: i32,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub details: Option<Vec<serde_json::Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UploadToFileSearchStoreRequest {
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_metadata: Option<Vec<CustomMetadata>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub chunking_config: Option<ChunkingConfig>,
#[serde(
with = "mime_as_string::optional",
skip_serializing_if = "Option::is_none"
)]
pub mime_type: Option<mime::Mime>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ImportFileRequest {
pub file_name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub custom_metadata: Option<Vec<CustomMetadata>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub chunking_config: Option<ChunkingConfig>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListFileSearchStoresResponse {
pub file_search_stores: Vec<FileSearchStore>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_page_token: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ListDocumentsResponse {
pub documents: Vec<Document>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_page_token: Option<String>,
}
pub fn extract_store_name(full_name: &str) -> Result<String, crate::client::Error> {
let mut parts = full_name.split('/');
if parts.next() == Some("fileSearchStores") {
if let Some(store_id) = parts.next() {
return Ok(format!("fileSearchStores/{}", store_id));
}
}
Err(crate::client::Error::InvalidResourceName {
name: full_name.to_string(),
})
}
pub fn extract_document_id(full_name: &str) -> Result<String, crate::client::Error> {
let mut parts = full_name.split('/');
if parts.next() == Some("fileSearchStores") {
if let Some(_store) = parts.next() {
if parts.next() == Some("documents") {
if let Some(doc_id) = parts.next() {
return Ok(doc_id.to_string());
}
}
}
}
Err(crate::client::Error::InvalidResourceName {
name: full_name.to_string(),
})
}