opendal/services/koofr/
config.rs1use std::fmt::Debug;
19
20use serde::Deserialize;
21use serde::Serialize;
22
23use super::KOOFR_SCHEME;
24use super::backend::KoofrBuilder;
25
26#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
28#[serde(default)]
29#[non_exhaustive]
30pub struct KoofrConfig {
31 pub root: Option<String>,
35 pub endpoint: String,
37 pub email: String,
39 pub password: Option<String>,
41}
42
43impl Debug for KoofrConfig {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 f.debug_struct("KoofrConfig")
46 .field("root", &self.root)
47 .field("email", &self.email)
48 .finish_non_exhaustive()
49 }
50}
51
52impl crate::Configurator for KoofrConfig {
53 type Builder = KoofrBuilder;
54
55 fn from_uri(uri: &crate::types::OperatorUri) -> crate::Result<Self> {
56 let authority = uri.authority().ok_or_else(|| {
57 crate::Error::new(crate::ErrorKind::ConfigInvalid, "uri authority is required")
58 .with_context("service", KOOFR_SCHEME)
59 })?;
60
61 let raw_path = uri.root().ok_or_else(|| {
62 crate::Error::new(
63 crate::ErrorKind::ConfigInvalid,
64 "uri path must contain email",
65 )
66 .with_context("service", KOOFR_SCHEME)
67 })?;
68
69 let mut segments = raw_path.splitn(2, '/');
70 let email = segments.next().filter(|s| !s.is_empty()).ok_or_else(|| {
71 crate::Error::new(
72 crate::ErrorKind::ConfigInvalid,
73 "email is required in uri path",
74 )
75 .with_context("service", KOOFR_SCHEME)
76 })?;
77
78 let mut map = uri.options().clone();
79 map.insert("endpoint".to_string(), format!("https://{authority}"));
80 map.insert("email".to_string(), email.to_string());
81
82 if let Some(rest) = segments.next() {
83 if !rest.is_empty() {
84 map.insert("root".to_string(), rest.to_string());
85 }
86 }
87
88 Self::from_iter(map)
89 }
90
91 #[allow(deprecated)]
92 fn into_builder(self) -> Self::Builder {
93 KoofrBuilder {
94 config: self,
95 http_client: None,
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::Configurator;
104 use crate::types::OperatorUri;
105
106 #[test]
107 fn from_uri_sets_endpoint_email_and_root() {
108 let uri = OperatorUri::new(
109 "koofr://api.koofr.net/me%40example.com/library",
110 Vec::<(String, String)>::new(),
111 )
112 .unwrap();
113
114 let cfg = KoofrConfig::from_uri(&uri).unwrap();
115 assert_eq!(cfg.endpoint, "https://api.koofr.net".to_string());
116 assert_eq!(cfg.email, "me@example.com".to_string());
117 assert_eq!(cfg.root.as_deref(), Some("library"));
118 }
119
120 #[test]
121 fn from_uri_requires_email_segment() {
122 let uri =
123 OperatorUri::new("koofr://api.koofr.net", Vec::<(String, String)>::new()).unwrap();
124
125 assert!(KoofrConfig::from_uri(&uri).is_err());
126 }
127}