Skip to main content

floe_core/config/
location.rs

1use std::path::{Path, PathBuf};
2
3use tempfile::TempDir;
4
5use crate::config::{ConfigBase, StorageDefinition};
6use crate::io::storage::{self, StorageClient};
7use crate::FloeResult;
8
9pub struct ConfigLocation {
10    pub path: PathBuf,
11    pub base: ConfigBase,
12    pub display: String,
13    _temp_dir: Option<TempDir>,
14}
15
16pub fn resolve_config_location(input: &str) -> FloeResult<ConfigLocation> {
17    if is_remote_uri(input) {
18        let temp_dir = TempDir::new()?;
19        let local_path = download_remote_config(input, temp_dir.path())?;
20        let base = ConfigBase::remote_from_uri(temp_dir.path().to_path_buf(), input)?;
21        Ok(ConfigLocation {
22            path: local_path,
23            base,
24            display: input.to_string(),
25            _temp_dir: Some(temp_dir),
26        })
27    } else {
28        let path = PathBuf::from(input);
29        let absolute = if path.is_absolute() {
30            path
31        } else {
32            std::env::current_dir()?.join(path)
33        };
34        let canonical = std::fs::canonicalize(&absolute)?;
35        let base = ConfigBase::local_from_path(&canonical);
36        Ok(ConfigLocation {
37            path: canonical.clone(),
38            base,
39            display: canonical.display().to_string(),
40            _temp_dir: None,
41        })
42    }
43}
44
45fn download_remote_config(uri: &str, temp_dir: &Path) -> FloeResult<PathBuf> {
46    if uri.starts_with("s3://") {
47        let location = storage::s3::parse_s3_uri(uri)?;
48        let client = storage::s3::S3Client::new(location.bucket, None)?;
49        return client.download_to_temp(uri, temp_dir);
50    }
51    if uri.starts_with("gs://") {
52        let location = storage::gcs::parse_gcs_uri(uri)?;
53        let client = storage::gcs::GcsClient::new(location.bucket)?;
54        return client.download_to_temp(uri, temp_dir);
55    }
56    if uri.starts_with("abfs://") {
57        let location = storage::adls::parse_adls_uri(uri)?;
58        let definition = StorageDefinition {
59            name: "config".to_string(),
60            fs_type: "adls".to_string(),
61            bucket: None,
62            region: None,
63            account: Some(location.account),
64            container: Some(location.container),
65            prefix: None,
66        };
67        let client = storage::adls::AdlsClient::new(&definition)?;
68        return client.download_to_temp(uri, temp_dir);
69    }
70    Err(format!("unsupported config uri: {}", uri).into())
71}
72
73fn is_remote_uri(value: &str) -> bool {
74    value.starts_with("s3://") || value.starts_with("gs://") || value.starts_with("abfs://")
75}