use std::collections::HashMap;
use std::path::PathBuf;
#[derive(Clone, Debug, Default)]
pub struct SparklessConfig {
pub warehouse_dir: Option<PathBuf>,
pub temp_dir: Option<PathBuf>,
pub case_sensitive: bool,
pub extra: HashMap<String, String>,
}
impl SparklessConfig {
pub fn from_env() -> Self {
let warehouse_dir = std::env::var("ROBIN_SPARKLESS_WAREHOUSE_DIR")
.ok()
.filter(|s| !s.is_empty())
.map(PathBuf::from);
let temp_dir = std::env::var("ROBIN_SPARKLESS_TEMP_DIR")
.ok()
.filter(|s| !s.is_empty())
.map(PathBuf::from);
let case_sensitive = std::env::var("ROBIN_SPARKLESS_CASE_SENSITIVE")
.map(|v| v.eq_ignore_ascii_case("true") || v == "1")
.unwrap_or(false);
let prefix = "ROBIN_SPARKLESS_CONFIG_";
let mut extra = HashMap::new();
for (k, v) in std::env::vars() {
if let Some(suffix) = k.strip_prefix(prefix) {
let key = suffix.replace('_', ".");
if !key.is_empty() && !v.is_empty() {
extra.insert(key, v);
}
}
}
SparklessConfig {
warehouse_dir,
temp_dir,
case_sensitive,
extra,
}
}
pub fn to_session_config(&self) -> HashMap<String, String> {
let mut m = self.extra.clone();
if let Some(ref d) = self.warehouse_dir
&& let Some(s) = d.to_str()
{
m.insert("spark.sql.warehouse.dir".to_string(), s.to_string());
}
m.insert(
"spark.sql.caseSensitive".to_string(),
if self.case_sensitive { "true" } else { "false" }.to_string(),
);
m
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn config_default() {
let c = SparklessConfig::default();
assert!(c.warehouse_dir.is_none());
assert!(c.temp_dir.is_none());
assert!(!c.case_sensitive);
assert!(c.extra.is_empty());
}
#[test]
fn to_session_config_empty() {
let c = SparklessConfig::default();
let m = c.to_session_config();
assert_eq!(m.get("spark.sql.caseSensitive").unwrap(), "false");
assert!(!m.contains_key("spark.sql.warehouse.dir"));
}
#[test]
fn to_session_config_warehouse_and_case_sensitive() {
let c = SparklessConfig {
warehouse_dir: Some(PathBuf::from("/tmp/wh")),
case_sensitive: true,
..Default::default()
};
let m = c.to_session_config();
assert_eq!(m.get("spark.sql.warehouse.dir").unwrap(), "/tmp/wh");
assert_eq!(m.get("spark.sql.caseSensitive").unwrap(), "true");
}
#[test]
fn to_session_config_extra_preserved() {
let mut extra = std::collections::HashMap::new();
extra.insert("spark.app.name".to_string(), "MyApp".to_string());
let c = SparklessConfig {
extra,
..Default::default()
};
let m = c.to_session_config();
assert_eq!(m.get("spark.app.name").unwrap(), "MyApp");
assert_eq!(m.get("spark.sql.caseSensitive").unwrap(), "false");
}
}