use std::path::{Path, PathBuf};
use serde::{Deserialize, Serialize};
use crate::StorageError;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LanceConfig {
pub path: PathBuf,
pub default_vector_column: Option<String>,
}
impl LanceConfig {
#[must_use]
pub fn embedded_path(path: impl Into<PathBuf>) -> Self {
Self {
path: path.into(),
default_vector_column: Some("vector".into()),
}
}
pub(crate) fn validate(&self) -> Result<(), StorageError> {
if self.path.as_os_str().is_empty() {
return Err(StorageError::InvalidConfig(
"LanceConfig.path must not be empty".into(),
));
}
let path = self.uri_string();
let bytes = path.as_bytes();
let windows_drive = bytes.len() >= 3
&& bytes[0].is_ascii_alphabetic()
&& bytes[1] == b':'
&& matches!(bytes[2], b'/' | b'\\');
if path != "memory://" && !windows_drive && url::Url::parse(&path).is_ok() {
return Err(StorageError::InvalidConfig(
"LanceConfig.path accepts filesystem paths or memory://, not native URI routes"
.into(),
));
}
if self
.default_vector_column
.as_deref()
.is_some_and(|column| column.trim().is_empty())
{
return Err(StorageError::InvalidConfig(
"LanceConfig.default_vector_column must not be empty when configured".into(),
));
}
Ok(())
}
pub(crate) fn uri_string(&self) -> String {
self.path.to_string_lossy().into_owned()
}
pub(crate) fn path(&self) -> &Path {
&self.path
}
}