opendal/types/capability.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;
19
20/// Capability defines the supported operations and their constraints for a storage Operator.
21///
22/// # Overview
23///
24/// This structure provides a comprehensive description of an Operator's capabilities,
25/// including:
26///
27/// - Basic operations support (read, write, delete, etc.)
28/// - Advanced operation variants (conditional operations, metadata handling)
29/// - Operational constraints (size limits, batch limitations)
30///
31/// # Capability Types
32///
33/// Every operator maintains two capability sets:
34///
35/// 1. [`OperatorInfo::native_capability`][crate::OperatorInfo::native_capability]:
36/// Represents operations natively supported by the storage backend.
37///
38/// 2. [`OperatorInfo::full_capability`][crate::OperatorInfo::full_capability]:
39/// Represents all available operations, including those implemented through
40/// alternative mechanisms.
41///
42/// # Implementation Details
43///
44/// Some operations might be available even when not natively supported by the
45/// backend. For example:
46///
47/// - Blocking operations are provided through the BlockingLayer
48///
49/// Developers should:
50/// - Use `full_capability` to determine available operations
51/// - Use `native_capability` to identify optimized operations
52///
53/// # Field Naming Conventions
54///
55/// Fields follow these naming patterns:
56///
57/// - Basic operations: Simple lowercase (e.g., `read`, `write`)
58/// - Compound operations: Underscore-separated (e.g., `presign_read`)
59/// - Variants: Capability description (e.g., `write_can_empty`)
60/// - Parameterized operations: With-style (e.g., `read_with_if_match`)
61/// - Limitations: Constraint description (e.g., `write_multi_max_size`)
62/// - Metadata Results: Returning metadata capabilities (e.g., `stat_has_content_length`)
63///
64/// All capability fields are public and can be accessed directly.
65#[derive(Copy, Clone, Default)]
66pub struct Capability {
67 /// Indicates if the operator supports metadata retrieval operations.
68 pub stat: bool,
69 /// Indicates if conditional stat operations using If-Match are supported.
70 pub stat_with_if_match: bool,
71 /// Indicates if conditional stat operations using If-None-Match are supported.
72 pub stat_with_if_none_match: bool,
73 /// Indicates if conditional stat operations using If-Modified-Since are supported.
74 pub stat_with_if_modified_since: bool,
75 /// Indicates if conditional stat operations using If-Unmodified-Since are supported.
76 pub stat_with_if_unmodified_since: bool,
77 /// Indicates if Cache-Control header override is supported during stat operations.
78 pub stat_with_override_cache_control: bool,
79 /// Indicates if Content-Disposition header override is supported during stat operations.
80 pub stat_with_override_content_disposition: bool,
81 /// Indicates if Content-Type header override is supported during stat operations.
82 pub stat_with_override_content_type: bool,
83 /// Indicates if versions stat operations are supported.
84 pub stat_with_version: bool,
85
86 /// Indicates if the operator supports read operations.
87 pub read: bool,
88 /// Indicates if conditional read operations using If-Match are supported.
89 pub read_with_if_match: bool,
90 /// Indicates if conditional read operations using If-None-Match are supported.
91 pub read_with_if_none_match: bool,
92 /// Indicates if conditional read operations using If-Modified-Since are supported.
93 pub read_with_if_modified_since: bool,
94 /// Indicates if conditional read operations using If-Unmodified-Since are supported.
95 pub read_with_if_unmodified_since: bool,
96 /// Indicates if Cache-Control header override is supported during read operations.
97 pub read_with_override_cache_control: bool,
98 /// Indicates if Content-Disposition header override is supported during read operations.
99 pub read_with_override_content_disposition: bool,
100 /// Indicates if Content-Type header override is supported during read operations.
101 pub read_with_override_content_type: bool,
102 /// Indicates if versions read operations are supported.
103 pub read_with_version: bool,
104
105 /// Indicates if the operator supports write operations.
106 pub write: bool,
107 /// Indicates if multiple write operations can be performed on the same object.
108 pub write_can_multi: bool,
109 /// Indicates if writing empty content is supported.
110 pub write_can_empty: bool,
111 /// Indicates if append operations are supported.
112 pub write_can_append: bool,
113 /// Indicates if Content-Type can be specified during write operations.
114 pub write_with_content_type: bool,
115 /// Indicates if Content-Disposition can be specified during write operations.
116 pub write_with_content_disposition: bool,
117 /// Indicates if Content-Encoding can be specified during write operations.
118 pub write_with_content_encoding: bool,
119 /// Indicates if Cache-Control can be specified during write operations.
120 pub write_with_cache_control: bool,
121 /// Indicates if conditional write operations using If-Match are supported.
122 pub write_with_if_match: bool,
123 /// Indicates if conditional write operations using If-None-Match are supported.
124 pub write_with_if_none_match: bool,
125 /// Indicates if write operations can be conditional on object non-existence.
126 pub write_with_if_not_exists: bool,
127 /// Indicates if custom user metadata can be attached during write operations.
128 pub write_with_user_metadata: bool,
129 /// Maximum size supported for multipart uploads.
130 /// For example, AWS S3 supports up to 5GiB per part in multipart uploads.
131 pub write_multi_max_size: Option<usize>,
132 /// Minimum size required for multipart uploads (except for the last part).
133 /// For example, AWS S3 requires at least 5MiB per part.
134 pub write_multi_min_size: Option<usize>,
135 /// Maximum total size supported for write operations.
136 /// For example, Cloudflare D1 has a 1MB total size limit.
137 pub write_total_max_size: Option<usize>,
138
139 /// Indicates if directory creation is supported.
140 pub create_dir: bool,
141
142 /// Indicates if delete operations are supported.
143 pub delete: bool,
144 /// Indicates if versions delete operations are supported.
145 pub delete_with_version: bool,
146 /// Maximum size supported for single delete operations.
147 pub delete_max_size: Option<usize>,
148
149 /// Indicates if copy operations are supported.
150 pub copy: bool,
151
152 /// Indicates if rename operations are supported.
153 pub rename: bool,
154
155 /// Indicates if list operations are supported.
156 pub list: bool,
157 /// Indicates if list operations support result limiting.
158 pub list_with_limit: bool,
159 /// Indicates if list operations support continuation from a specific point.
160 pub list_with_start_after: bool,
161 /// Indicates if recursive listing is supported.
162 pub list_with_recursive: bool,
163 /// Indicates if versions listing is supported.
164 #[deprecated(since = "0.51.1", note = "use with_versions instead")]
165 pub list_with_version: bool,
166 /// Indicates if listing with versions included is supported.
167 pub list_with_versions: bool,
168 /// Indicates if listing with deleted files included is supported.
169 pub list_with_deleted: bool,
170
171 /// Indicates if presigned URL generation is supported.
172 pub presign: bool,
173 /// Indicates if presigned URLs for read operations are supported.
174 pub presign_read: bool,
175 /// Indicates if presigned URLs for stat operations are supported.
176 pub presign_stat: bool,
177 /// Indicates if presigned URLs for write operations are supported.
178 pub presign_write: bool,
179 /// Indicates if presigned URLs for delete operations are supported.
180 pub presign_delete: bool,
181
182 /// Indicate if the operator supports shared access.
183 pub shared: bool,
184}
185
186impl Debug for Capability {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 // NOTE: All services in opendal are readable.
189 if self.read {
190 f.write_str("Read")?;
191 }
192 if self.write {
193 f.write_str("| Write")?;
194 }
195 if self.list {
196 f.write_str("| List")?;
197 }
198 if self.presign {
199 f.write_str("| Presign")?;
200 }
201 if self.shared {
202 f.write_str("| Shared")?;
203 }
204
205 Ok(())
206 }
207}