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