opendal/services/memory/
backend.rs1use std::fmt::Debug;
19use std::sync::Arc;
20
21use super::core::*;
22use super::delete::MemoryDeleter;
23use super::lister::MemoryLister;
24use super::writer::MemoryWriter;
25use crate::raw::oio;
26use crate::raw::*;
27use crate::services::MemoryConfig;
28use crate::*;
29
30impl Configurator for MemoryConfig {
31 type Builder = MemoryBuilder;
32 fn into_builder(self) -> Self::Builder {
33 MemoryBuilder { config: self }
34 }
35}
36
37#[doc = include_str!("docs.md")]
39#[derive(Default)]
40pub struct MemoryBuilder {
41 config: MemoryConfig,
42}
43
44impl MemoryBuilder {
45 pub fn root(mut self, path: &str) -> Self {
47 self.config.root = Some(path.into());
48 self
49 }
50}
51
52impl Builder for MemoryBuilder {
53 const SCHEME: Scheme = Scheme::Memory;
54 type Config = MemoryConfig;
55
56 fn build(self) -> Result<impl Access> {
57 let root = normalize_root(self.config.root.as_deref().unwrap_or("/"));
58
59 let core = MemoryCore::new();
60 Ok(MemoryAccessor::new(core).with_normalized_root(root))
61 }
62}
63
64#[derive(Debug, Clone)]
66pub struct MemoryAccessor {
67 core: Arc<MemoryCore>,
68 root: String,
69 info: Arc<AccessorInfo>,
70}
71
72impl MemoryAccessor {
73 fn new(core: MemoryCore) -> Self {
74 let info = AccessorInfo::default();
75 info.set_scheme(Scheme::Memory);
76 info.set_name(&format!("{:p}", Arc::as_ptr(&core.data)));
77 info.set_root("/");
78 info.set_native_capability(Capability {
79 read: true,
80 write: true,
81 write_can_empty: true,
82 write_with_cache_control: true,
83 write_with_content_type: true,
84 write_with_content_disposition: true,
85 write_with_content_encoding: true,
86 delete: true,
87 stat: true,
88 list: true,
89 list_with_recursive: true,
90 shared: false,
91 ..Default::default()
92 });
93
94 Self {
95 core: Arc::new(core),
96 root: "/".to_string(),
97 info: Arc::new(info),
98 }
99 }
100
101 fn with_normalized_root(mut self, root: String) -> Self {
102 self.info.set_root(&root);
103 self.root = root;
104 self
105 }
106}
107
108impl Access for MemoryAccessor {
109 type Reader = Buffer;
110 type Writer = MemoryWriter;
111 type Lister = oio::HierarchyLister<MemoryLister>;
112 type Deleter = oio::OneShotDeleter<MemoryDeleter>;
113
114 fn info(&self) -> Arc<AccessorInfo> {
115 self.info.clone()
116 }
117
118 async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> {
119 let p = build_abs_path(&self.root, path);
120
121 if p == build_abs_path(&self.root, "") {
122 Ok(RpStat::new(Metadata::new(EntryMode::DIR)))
123 } else {
124 match self.core.get(&p)? {
125 Some(value) => Ok(RpStat::new(value.metadata)),
126 None => Err(Error::new(
127 ErrorKind::NotFound,
128 "memory doesn't have this path",
129 )),
130 }
131 }
132 }
133
134 async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
135 let p = build_abs_path(&self.root, path);
136
137 let value = match self.core.get(&p)? {
138 Some(value) => value,
139 None => {
140 return Err(Error::new(
141 ErrorKind::NotFound,
142 "memory doesn't have this path",
143 ))
144 }
145 };
146
147 Ok((
148 RpRead::new(),
149 value.content.slice(args.range().to_range_as_usize()),
150 ))
151 }
152
153 async fn write(&self, path: &str, args: OpWrite) -> Result<(RpWrite, Self::Writer)> {
154 let p = build_abs_path(&self.root, path);
155 Ok((
156 RpWrite::new(),
157 MemoryWriter::new(self.core.clone(), p, args),
158 ))
159 }
160
161 async fn delete(&self) -> Result<(RpDelete, Self::Deleter)> {
162 Ok((
163 RpDelete::default(),
164 oio::OneShotDeleter::new(MemoryDeleter::new(self.core.clone(), self.root.clone())),
165 ))
166 }
167
168 async fn list(&self, path: &str, args: OpList) -> Result<(RpList, Self::Lister)> {
169 let p = build_abs_path(&self.root, path);
170 let keys = self.core.scan(&p)?;
171 let lister = MemoryLister::new(&self.root, keys);
172 let lister = oio::HierarchyLister::new(lister, path, args.recursive());
173
174 Ok((RpList::default(), lister))
175 }
176}
177
178#[cfg(test)]
179mod tests {
180 use super::*;
181
182 #[test]
183 fn test_accessor_metadata_name() {
184 let b1 = MemoryBuilder::default().build().unwrap();
185 assert_eq!(b1.info().name(), b1.info().name());
186
187 let b2 = MemoryBuilder::default().build().unwrap();
188 assert_ne!(b1.info().name(), b2.info().name())
189 }
190}