opendal/services/surrealdb/
config.rs1use std::fmt::Debug;
19
20use serde::Deserialize;
21use serde::Serialize;
22
23use super::backend::SurrealdbBuilder;
24
25#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
27#[serde(default)]
28#[non_exhaustive]
29pub struct SurrealdbConfig {
30 pub connection_string: Option<String>,
32 pub username: Option<String>,
34 pub password: Option<String>,
36 pub namespace: Option<String>,
38 pub database: Option<String>,
40 pub table: Option<String>,
42 pub key_field: Option<String>,
44 pub value_field: Option<String>,
46 pub root: Option<String>,
48}
49
50impl Debug for SurrealdbConfig {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 f.debug_struct("SurrealdbConfig")
53 .field("username", &self.username)
54 .field("namespace", &self.namespace)
55 .field("database", &self.database)
56 .field("table", &self.table)
57 .field("key_field", &self.key_field)
58 .field("value_field", &self.value_field)
59 .field("root", &self.root)
60 .finish_non_exhaustive()
61 }
62}
63
64impl crate::Configurator for SurrealdbConfig {
65 type Builder = SurrealdbBuilder;
66
67 fn from_uri(uri: &crate::types::OperatorUri) -> crate::Result<Self> {
68 let mut map = uri.options().clone();
69
70 if let Some(authority) = uri.authority() {
71 map.entry("connection_string".to_string())
72 .or_insert_with(|| format!("ws://{authority}"));
73 }
74
75 if let Some(path) = uri.root() {
76 if !path.is_empty() {
77 let mut segments = path.splitn(4, '/');
78 if let Some(namespace) = segments.next() {
79 if !namespace.is_empty() {
80 map.entry("namespace".to_string())
81 .or_insert_with(|| namespace.to_string());
82 }
83 }
84 if let Some(database) = segments.next() {
85 if !database.is_empty() {
86 map.entry("database".to_string())
87 .or_insert_with(|| database.to_string());
88 }
89 }
90 if let Some(table) = segments.next() {
91 if !table.is_empty() {
92 map.entry("table".to_string())
93 .or_insert_with(|| table.to_string());
94 }
95 }
96 if let Some(rest) = segments.next() {
97 if !rest.is_empty() {
98 map.insert("root".to_string(), rest.to_string());
99 }
100 }
101 }
102 }
103
104 Self::from_iter(map)
105 }
106
107 fn into_builder(self) -> Self::Builder {
108 SurrealdbBuilder { config: self }
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use crate::Configurator;
116 use crate::types::OperatorUri;
117
118 #[test]
119 fn from_uri_sets_connection_namespace_database_table_and_root() {
120 let uri = OperatorUri::new(
121 "surrealdb://db.example.com:8000/project/app/cache/static",
122 Vec::<(String, String)>::new(),
123 )
124 .unwrap();
125
126 let cfg = SurrealdbConfig::from_uri(&uri).unwrap();
127 assert_eq!(
128 cfg.connection_string.as_deref(),
129 Some("ws://db.example.com:8000")
130 );
131 assert_eq!(cfg.namespace.as_deref(), Some("project"));
132 assert_eq!(cfg.database.as_deref(), Some("app"));
133 assert_eq!(cfg.table.as_deref(), Some("cache"));
134 assert_eq!(cfg.root.as_deref(), Some("static"));
135 }
136}