opendal/raw/adapters/typed_kv/
api.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use std::fmt::Debug;
19use std::future::ready;
20use std::future::Future;
21use std::mem::size_of;
22
23use chrono::Utc;
24
25use crate::raw::MaybeSend;
26use crate::Buffer;
27use crate::EntryMode;
28use crate::Error;
29use crate::ErrorKind;
30use crate::Metadata;
31use crate::Result;
32use crate::Scheme;
33
34/// Adapter is the typed adapter to underlying kv services.
35///
36/// By implement this trait, any kv service can work as an OpenDAL Service.
37///
38/// # Notes
39///
40/// `typed_kv::Adapter` is the typed version of `kv::Adapter`. It's more
41/// efficient if the underlying kv service can store data with its type. For
42/// example, we can store `Bytes` along with its metadata so that we don't
43/// need to serialize/deserialize it when we get it from the service.
44///
45/// Ideally, we should use `typed_kv::Adapter` instead of `kv::Adapter` for
46/// in-memory rust libs like moka and dashmap.
47pub trait Adapter: Send + Sync + Debug + Unpin + 'static {
48    /// Return the info of this key value accessor.
49    fn info(&self) -> Info;
50
51    /// Get a value from adapter.
52    fn get(&self, path: &str) -> impl Future<Output = Result<Option<Value>>> + MaybeSend;
53
54    /// Get a value from adapter.
55    fn blocking_get(&self, path: &str) -> Result<Option<Value>>;
56
57    /// Set a value into adapter.
58    fn set(&self, path: &str, value: Value) -> impl Future<Output = Result<()>> + MaybeSend;
59
60    /// Set a value into adapter.
61    fn blocking_set(&self, path: &str, value: Value) -> Result<()>;
62
63    /// Delete a value from adapter.
64    fn delete(&self, path: &str) -> impl Future<Output = Result<()>> + MaybeSend;
65
66    /// Delete a value from adapter.
67    fn blocking_delete(&self, path: &str) -> Result<()>;
68
69    /// Scan a key prefix to get all keys that start with this key.
70    fn scan(&self, path: &str) -> impl Future<Output = Result<Vec<String>>> + MaybeSend {
71        let _ = path;
72
73        ready(Err(Error::new(
74            ErrorKind::Unsupported,
75            "typed_kv adapter doesn't support this operation",
76        )
77        .with_operation("typed_kv::Adapter::scan")))
78    }
79
80    /// Scan a key prefix to get all keys that start with this key
81    /// in blocking way.
82    fn blocking_scan(&self, path: &str) -> Result<Vec<String>> {
83        let _ = path;
84
85        Err(Error::new(
86            ErrorKind::Unsupported,
87            "typed_kv adapter doesn't support this operation",
88        )
89        .with_operation("typed_kv::Adapter::blocking_scan"))
90    }
91}
92
93/// Value is the typed value stored in adapter.
94///
95/// It's cheap to clone so that users can read data without extra copy.
96#[derive(Debug, Clone)]
97pub struct Value {
98    /// Metadata of this value.
99    pub metadata: Metadata,
100    /// The corresponding content of this value.
101    pub value: Buffer,
102}
103
104impl Value {
105    /// Create a new dir of value.
106    pub fn new_dir() -> Self {
107        Self {
108            metadata: Metadata::new(EntryMode::DIR)
109                .with_content_length(0)
110                .with_last_modified(Utc::now()),
111            value: Buffer::new(),
112        }
113    }
114
115    /// Size returns the in-memory size of Value.
116    pub fn size(&self) -> usize {
117        size_of::<Metadata>() + self.value.len()
118    }
119}
120
121/// Capability is used to describe what operations are supported
122/// by Typed KV Operator.
123#[derive(Copy, Clone, Default)]
124pub struct Capability {
125    /// If typed_kv operator supports get natively.
126    pub get: bool,
127    /// If typed_kv operator supports set natively.
128    pub set: bool,
129    /// If typed_kv operator supports delete natively.
130    pub delete: bool,
131    /// If typed_kv operator supports scan natively.
132    pub scan: bool,
133    /// If typed_kv operator supports shared access.
134    pub shared: bool,
135}
136
137impl Debug for Capability {
138    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
139        let mut s = vec![];
140
141        if self.get {
142            s.push("Get")
143        }
144        if self.set {
145            s.push("Set");
146        }
147        if self.delete {
148            s.push("Delete");
149        }
150        if self.scan {
151            s.push("Scan");
152        }
153        if self.shared {
154            s.push("Shared");
155        }
156
157        write!(f, "{{ {} }}", s.join(" | "))
158    }
159}
160
161/// Info for this key value accessor.
162pub struct Info {
163    scheme: Scheme,
164    name: String,
165    capabilities: Capability,
166}
167
168impl Info {
169    /// Create a new KeyValueAccessorInfo.
170    pub fn new(scheme: Scheme, name: &str, capabilities: Capability) -> Self {
171        Self {
172            scheme,
173            name: name.to_string(),
174            capabilities,
175        }
176    }
177
178    /// Get the scheme.
179    pub fn scheme(&self) -> Scheme {
180        self.scheme
181    }
182
183    /// Get the name.
184    pub fn name(&self) -> &str {
185        &self.name
186    }
187
188    /// Get the capabilities.
189    pub fn capabilities(&self) -> Capability {
190        self.capabilities
191    }
192}