opendal_core/services/azdls/
config.rs1use std::fmt::Debug;
19
20use serde::Deserialize;
21use serde::Serialize;
22
23use super::AZDLS_SCHEME;
24use super::backend::AzdlsBuilder;
25
26#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
28pub struct AzdlsConfig {
29 pub root: Option<String>,
31 pub filesystem: String,
33 pub endpoint: Option<String>,
35 pub account_name: Option<String>,
37 pub account_key: Option<String>,
40 pub client_secret: Option<String>,
44 pub tenant_id: Option<String>,
48 pub client_id: Option<String>,
52 pub sas_token: Option<String>,
56 pub authority_host: Option<String>,
61}
62
63impl Debug for AzdlsConfig {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 f.debug_struct("AzdlsConfig")
66 .field("root", &self.root)
67 .field("filesystem", &self.filesystem)
68 .field("endpoint", &self.endpoint)
69 .finish_non_exhaustive()
70 }
71}
72
73impl crate::Configurator for AzdlsConfig {
74 type Builder = AzdlsBuilder;
75
76 fn from_uri(uri: &crate::types::OperatorUri) -> crate::Result<Self> {
77 let mut map = uri.options().clone();
78 if let Some(authority) = uri.authority() {
79 map.insert("endpoint".to_string(), format!("https://{authority}"));
80 }
81
82 if let Some(host) = uri.name() {
83 if let Some(account) = host.split('.').next() {
84 if !account.is_empty() {
85 map.entry("account_name".to_string())
86 .or_insert_with(|| account.to_string());
87 }
88 }
89 }
90
91 if let Some(root) = uri.root() {
92 if let Some((filesystem, rest)) = root.split_once('/') {
93 if filesystem.is_empty() {
94 return Err(crate::Error::new(
95 crate::ErrorKind::ConfigInvalid,
96 "filesystem is required in uri path",
97 )
98 .with_context("service", AZDLS_SCHEME));
99 }
100 map.insert("filesystem".to_string(), filesystem.to_string());
101 if !rest.is_empty() {
102 map.insert("root".to_string(), rest.to_string());
103 }
104 } else if !root.is_empty() {
105 map.insert("filesystem".to_string(), root.to_string());
106 }
107 }
108
109 if !map.contains_key("filesystem") {
110 return Err(crate::Error::new(
111 crate::ErrorKind::ConfigInvalid,
112 "filesystem is required",
113 )
114 .with_context("service", AZDLS_SCHEME));
115 }
116
117 Self::from_iter(map)
118 }
119
120 #[allow(deprecated)]
121 fn into_builder(self) -> Self::Builder {
122 AzdlsBuilder {
123 config: self,
124 http_client: None,
125 }
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132 use crate::Configurator;
133 use crate::types::OperatorUri;
134
135 #[test]
136 fn from_uri_sets_endpoint_filesystem_root_and_account() {
137 let uri = OperatorUri::new(
138 "azdls://account.dfs.core.windows.net/fs/data/2024",
139 Vec::<(String, String)>::new(),
140 )
141 .unwrap();
142
143 let cfg = AzdlsConfig::from_uri(&uri).unwrap();
144 assert_eq!(
145 cfg.endpoint.as_deref(),
146 Some("https://account.dfs.core.windows.net")
147 );
148 assert_eq!(cfg.filesystem, "fs".to_string());
149 assert_eq!(cfg.root.as_deref(), Some("data/2024"));
150 assert_eq!(cfg.account_name.as_deref(), Some("account"));
151 }
152
153 #[test]
154 fn from_uri_accepts_filesystem_from_query() {
155 let uri = OperatorUri::new(
156 "azdls://account.dfs.core.windows.net",
157 vec![("filesystem".to_string(), "logs".to_string())],
158 )
159 .unwrap();
160
161 let cfg = AzdlsConfig::from_uri(&uri).unwrap();
162 assert_eq!(cfg.filesystem, "logs".to_string());
163 }
164}