use url::Url;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DatasetName {
pub namespace: String,
pub name: String,
}
impl DatasetName {
pub fn from_location(url: &Url) -> Self {
let scheme = url.scheme();
match scheme {
"s3" | "s3a" | "gs" | "gcs" | "abfs" | "abfss" | "wasbs" => {
let bucket = url.host_str().unwrap_or_default();
let name = url.path().trim_start_matches('/').to_string();
DatasetName {
namespace: format!("{scheme}://{bucket}"),
name,
}
}
"file" => DatasetName {
namespace: "file".to_string(),
name: url.path().to_string(),
},
_ => {
let host = url.host_str().unwrap_or_default();
DatasetName {
namespace: format!("{scheme}://{host}"),
name: url.path().trim_start_matches('/').to_string(),
}
}
}
}
pub fn from_table_ref(default_namespace: &str, table_ref: &str) -> Self {
DatasetName {
namespace: default_namespace.to_string(),
name: table_ref.to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn s3_location() {
let url = Url::parse("s3://open-lakehouse/warehouse/t1").unwrap();
let n = DatasetName::from_location(&url);
assert_eq!(n.namespace, "s3://open-lakehouse");
assert_eq!(n.name, "warehouse/t1");
}
#[test]
fn file_location() {
let url = Url::parse("file:///tmp/data/t").unwrap();
let n = DatasetName::from_location(&url);
assert_eq!(n.namespace, "file");
assert_eq!(n.name, "/tmp/data/t");
}
}