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    /// Set a value into adapter.
55    fn set(&self, path: &str, value: Value) -> impl Future<Output = Result<()>> + MaybeSend;
56
57    /// Delete a value from adapter.
58    fn delete(&self, path: &str) -> impl Future<Output = Result<()>> + MaybeSend;
59
60    /// Scan a key prefix to get all keys that start with this key.
61    fn scan(&self, path: &str) -> impl Future<Output = Result<Vec<String>>> + MaybeSend {
62        let _ = path;
63
64        ready(Err(Error::new(
65            ErrorKind::Unsupported,
66            "typed_kv adapter doesn't support this operation",
67        )
68        .with_operation("typed_kv::Adapter::scan")))
69    }
70}
71
72/// Value is the typed value stored in adapter.
73///
74/// It's cheap to clone so that users can read data without extra copy.
75#[derive(Debug, Clone)]
76pub struct Value {
77    /// Metadata of this value.
78    pub metadata: Metadata,
79    /// The corresponding content of this value.
80    pub value: Buffer,
81}
82
83impl Value {
84    /// Create a new dir of value.
85    pub fn new_dir() -> Self {
86        Self {
87            metadata: Metadata::new(EntryMode::DIR)
88                .with_content_length(0)
89                .with_last_modified(Utc::now()),
90            value: Buffer::new(),
91        }
92    }
93
94    /// Size returns the in-memory size of Value.
95    pub fn size(&self) -> usize {
96        size_of::<Metadata>() + self.value.len()
97    }
98}
99
100/// Capability is used to describe what operations are supported
101/// by Typed KV Operator.
102#[derive(Copy, Clone, Default)]
103pub struct Capability {
104    /// If typed_kv operator supports get natively.
105    pub get: bool,
106    /// If typed_kv operator supports set natively.
107    pub set: bool,
108    /// If typed_kv operator supports delete natively.
109    pub delete: bool,
110    /// If typed_kv operator supports scan natively.
111    pub scan: bool,
112    /// If typed_kv operator supports shared access.
113    pub shared: bool,
114}
115
116impl Debug for Capability {
117    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
118        let mut s = vec![];
119
120        if self.get {
121            s.push("Get")
122        }
123        if self.set {
124            s.push("Set");
125        }
126        if self.delete {
127            s.push("Delete");
128        }
129        if self.scan {
130            s.push("Scan");
131        }
132        if self.shared {
133            s.push("Shared");
134        }
135
136        write!(f, "{{ {} }}", s.join(" | "))
137    }
138}
139
140/// Info for this key value accessor.
141pub struct Info {
142    scheme: Scheme,
143    name: String,
144    capabilities: Capability,
145}
146
147impl Info {
148    /// Create a new KeyValueAccessorInfo.
149    pub fn new(scheme: Scheme, name: &str, capabilities: Capability) -> Self {
150        Self {
151            scheme,
152            name: name.to_string(),
153            capabilities,
154        }
155    }
156
157    /// Get the scheme.
158    pub fn scheme(&self) -> Scheme {
159        self.scheme
160    }
161
162    /// Get the name.
163    pub fn name(&self) -> &str {
164        &self.name
165    }
166
167    /// Get the capabilities.
168    pub fn capabilities(&self) -> Capability {
169        self.capabilities
170    }
171}