opendal/services/cacache/
backend.rs1use std::fmt::Debug;
19use std::fmt::Formatter;
20use std::str;
21
22use cacache;
23
24use crate::raw::adapters::kv;
25use crate::raw::Access;
26use crate::services::CacacheConfig;
27use crate::Builder;
28use crate::Error;
29use crate::ErrorKind;
30use crate::Scheme;
31use crate::*;
32
33impl Configurator for CacacheConfig {
34 type Builder = CacacheBuilder;
35 fn into_builder(self) -> Self::Builder {
36 CacacheBuilder { config: self }
37 }
38}
39
40#[doc = include_str!("docs.md")]
42#[derive(Default)]
43pub struct CacacheBuilder {
44 config: CacacheConfig,
45}
46
47impl CacacheBuilder {
48 pub fn datadir(mut self, path: &str) -> Self {
50 self.config.datadir = Some(path.into());
51 self
52 }
53}
54
55impl Builder for CacacheBuilder {
56 const SCHEME: Scheme = Scheme::Cacache;
57 type Config = CacacheConfig;
58
59 fn build(self) -> Result<impl Access> {
60 let datadir_path = self.config.datadir.ok_or_else(|| {
61 Error::new(ErrorKind::ConfigInvalid, "datadir is required but not set")
62 .with_context("service", Scheme::Cacache)
63 })?;
64
65 Ok(CacacheBackend::new(Adapter {
66 datadir: datadir_path,
67 }))
68 }
69}
70
71pub type CacacheBackend = kv::Backend<Adapter>;
73
74#[derive(Clone)]
75pub struct Adapter {
76 datadir: String,
77}
78
79impl Debug for Adapter {
80 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
81 let mut ds = f.debug_struct("Adapter");
82 ds.field("path", &self.datadir);
83 ds.finish()
84 }
85}
86
87impl kv::Adapter for Adapter {
88 type Scanner = ();
89
90 fn info(&self) -> kv::Info {
91 kv::Info::new(
92 Scheme::Cacache,
93 &self.datadir,
94 Capability {
95 read: true,
96 write: true,
97 delete: true,
98 blocking: true,
99 shared: false,
100 ..Default::default()
101 },
102 )
103 }
104
105 async fn get(&self, path: &str) -> Result<Option<Buffer>> {
106 let result = cacache::read(&self.datadir, path)
107 .await
108 .map_err(parse_error)?;
109 Ok(Some(Buffer::from(result)))
110 }
111
112 fn blocking_get(&self, path: &str) -> Result<Option<Buffer>> {
113 let result = cacache::read_sync(&self.datadir, path).map_err(parse_error)?;
114 Ok(Some(Buffer::from(result)))
115 }
116
117 async fn set(&self, path: &str, value: Buffer) -> Result<()> {
118 cacache::write(&self.datadir, path, value.to_vec())
119 .await
120 .map_err(parse_error)?;
121 Ok(())
122 }
123
124 fn blocking_set(&self, path: &str, value: Buffer) -> Result<()> {
125 cacache::write_sync(&self.datadir, path, value.to_vec()).map_err(parse_error)?;
126 Ok(())
127 }
128
129 async fn delete(&self, path: &str) -> Result<()> {
130 cacache::remove(&self.datadir, path)
131 .await
132 .map_err(parse_error)?;
133
134 Ok(())
135 }
136
137 fn blocking_delete(&self, path: &str) -> Result<()> {
138 cacache::remove_sync(&self.datadir, path).map_err(parse_error)?;
139
140 Ok(())
141 }
142}
143
144fn parse_error(err: cacache::Error) -> Error {
145 let kind = match err {
146 cacache::Error::EntryNotFound(_, _) => ErrorKind::NotFound,
147 _ => ErrorKind::Unexpected,
148 };
149
150 Error::new(kind, "error from cacache").set_source(err)
151}