use std::collections::HashMap;
pub struct CatalogOptions;
impl CatalogOptions {
pub const URI: &'static str = "uri";
pub const METASTORE: &'static str = "metastore";
pub const WAREHOUSE: &'static str = "warehouse";
pub const TOKEN_PROVIDER: &'static str = "token.provider";
pub const TOKEN: &'static str = "token";
pub const DATA_TOKEN_ENABLED: &'static str = "data-token.enabled";
pub const PREFIX: &'static str = "prefix";
pub const DLF_REGION: &'static str = "dlf.region";
pub const DLF_ACCESS_KEY_ID: &'static str = "dlf.access-key-id";
pub const DLF_ACCESS_KEY_SECRET: &'static str = "dlf.access-key-secret";
pub const DLF_ACCESS_SECURITY_TOKEN: &'static str = "dlf.security-token";
pub const DLF_SIGNING_ALGORITHM: &'static str = "dlf.signing-algorithm";
pub const DLF_TOKEN_LOADER: &'static str = "dlf.token-loader";
pub const DLF_TOKEN_ECS_METADATA_URL: &'static str = "dlf.token-ecs-metadata-url";
pub const DLF_TOKEN_ECS_ROLE_NAME: &'static str = "dlf.token-ecs-role-name";
pub const DLF_OSS_ENDPOINT: &'static str = "dlf.oss-endpoint";
}
#[derive(Debug, Clone, Default)]
pub struct Options {
data: HashMap<String, String>,
}
impl Options {
pub fn new() -> Self {
Options {
data: HashMap::new(),
}
}
pub fn from_map(data: HashMap<String, String>) -> Self {
Options { data }
}
pub fn to_map(&self) -> &HashMap<String, String> {
&self.data
}
pub fn get(&self, key: &str) -> Option<&String> {
self.data.get(key)
}
pub fn get_or_default(&self, key: &str, default: &str) -> String {
self.data
.get(key)
.cloned()
.unwrap_or_else(|| default.to_string())
}
pub fn set(&mut self, key: impl Into<String>, value: impl Into<String>) {
self.data.insert(key.into(), value.into());
}
pub fn contains(&self, key: &str) -> bool {
self.data.contains_key(key)
}
pub fn remove(&mut self, key: &str) -> Option<String> {
self.data.remove(key)
}
pub fn merge(&mut self, other: &Options) {
for (key, value) in &other.data {
self.data.insert(key.clone(), value.clone());
}
}
pub fn copy(&self) -> Self {
Options {
data: self.data.clone(),
}
}
pub fn extract_prefix_map(&self, prefix: &str) -> HashMap<String, String> {
let mut result = HashMap::new();
for (key, value) in &self.data {
if let Some(stripped) = key.strip_prefix(prefix) {
result.insert(stripped.to_string(), value.clone());
}
}
result
}
}
impl From<HashMap<String, String>> for Options {
fn from(data: HashMap<String, String>) -> Self {
Options { data }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_options_basic() {
let mut options = Options::new();
options.set("uri", "http://localhost:8080");
options.set("warehouse", "/data/warehouse");
assert_eq!(
options.get("uri"),
Some(&"http://localhost:8080".to_string())
);
assert_eq!(
options.get("warehouse"),
Some(&"/data/warehouse".to_string())
);
assert!(!options.contains("nonexistent"));
}
#[test]
fn test_options_extract_prefix() {
let mut options = Options::new();
options.set("header.Content-Type", "application/json");
options.set("header.Authorization", "Bearer token");
options.set("other.key", "value");
let headers = options.extract_prefix_map("header.");
assert_eq!(headers.len(), 2);
assert_eq!(
headers.get("Content-Type"),
Some(&"application/json".to_string())
);
assert_eq!(
headers.get("Authorization"),
Some(&"Bearer token".to_string())
);
}
#[test]
fn test_options_merge() {
let mut options1 = Options::new();
options1.set("key1", "value1");
let mut options2 = Options::new();
options2.set("key2", "value2");
options2.set("key1", "overwritten");
options1.merge(&options2);
assert_eq!(options1.get("key1"), Some(&"overwritten".to_string()));
assert_eq!(options1.get("key2"), Some(&"value2".to_string()));
}
}