object_store_opendal/service/
core.rs1use crate::{datetime_to_timestamp, timestamp_to_datetime};
19use object_store::{
20 Attribute, AttributeValue, GetOptions, GetRange, ObjectMeta, PutOptions, PutResult,
21};
22use opendal::raw::*;
23use opendal::*;
24use std::borrow::Cow;
25
26pub fn parse_op_stat(args: &OpStat) -> Result<GetOptions> {
28 let mut options = GetOptions {
29 head: true, ..Default::default()
31 };
32
33 if let Some(version) = args.version() {
34 options.version = Some(version.to_string());
35 }
36
37 if let Some(if_match) = args.if_match() {
38 options.if_match = Some(if_match.to_string());
39 }
40
41 if let Some(if_none_match) = args.if_none_match() {
42 options.if_none_match = Some(if_none_match.to_string());
43 }
44
45 if let Some(if_modified_since) = args.if_modified_since() {
46 options.if_modified_since = timestamp_to_datetime(if_modified_since);
47 }
48
49 if let Some(if_unmodified_since) = args.if_unmodified_since() {
50 options.if_unmodified_since = timestamp_to_datetime(if_unmodified_since);
51 }
52
53 Ok(options)
54}
55
56pub fn parse_op_read(args: &OpRead, range: BytesRange) -> Result<GetOptions> {
58 let mut options = GetOptions::default();
59
60 if let Some(version) = args.version() {
61 options.version = Some(version.to_string());
62 }
63
64 if let Some(if_match) = args.if_match() {
65 options.if_match = Some(if_match.to_string());
66 }
67
68 if let Some(if_none_match) = args.if_none_match() {
69 options.if_none_match = Some(if_none_match.to_string());
70 }
71
72 if let Some(if_modified_since) = args.if_modified_since() {
73 options.if_modified_since = timestamp_to_datetime(if_modified_since);
74 }
75
76 if let Some(if_unmodified_since) = args.if_unmodified_since() {
77 options.if_unmodified_since = timestamp_to_datetime(if_unmodified_since);
78 }
79
80 match range {
81 BytesRange::Range {
82 offset: 0,
83 size: None,
84 } => {}
85 BytesRange::Range { offset, size } => match size {
86 Some(size) => {
87 let end = offset.checked_add(size).ok_or_else(|| {
88 Error::new(ErrorKind::RangeNotSatisfied, "range exceeds content length")
89 .with_context("offset", offset)
90 .with_context("size", size)
91 })?;
92 options.range = Some(GetRange::Bounded(offset..end));
93 }
94 None => {
95 options.range = Some(GetRange::Offset(offset));
96 }
97 },
98 BytesRange::Suffix { size } => {
99 options.range = Some(GetRange::Suffix(size));
100 }
101 }
102
103 Ok(options)
104}
105
106pub fn parse_op_write(args: &OpWrite) -> Result<PutOptions> {
108 let mut opts = PutOptions::default();
109
110 if let Some(content_type) = args.content_type() {
111 opts.attributes.insert(
112 Attribute::ContentType,
113 AttributeValue::from(content_type.to_string()),
114 );
115 }
116
117 if let Some(content_disposition) = args.content_disposition() {
118 opts.attributes.insert(
119 Attribute::ContentDisposition,
120 AttributeValue::from(content_disposition.to_string()),
121 );
122 }
123
124 if let Some(cache_control) = args.cache_control() {
125 opts.attributes.insert(
126 Attribute::CacheControl,
127 AttributeValue::from(cache_control.to_string()),
128 );
129 }
130
131 if let Some(user_metadata) = args.user_metadata() {
132 for (key, value) in user_metadata {
133 opts.attributes.insert(
134 Attribute::Metadata(Cow::from(key.to_string())),
135 AttributeValue::from(value.to_string()),
136 );
137 }
138 }
139 Ok(opts)
140}
141
142pub fn format_put_multipart_options(opts: PutOptions) -> object_store::PutMultipartOptions {
144 object_store::PutMultipartOptions {
145 attributes: opts.attributes,
146 ..Default::default()
147 }
148}
149
150pub fn format_put_result(result: PutResult) -> Metadata {
152 let mut metadata = Metadata::new(EntryMode::FILE);
153 if let Some(etag) = &result.e_tag {
154 metadata.set_etag(etag);
155 }
156 if let Some(version) = &result.version {
157 metadata.set_version(version);
158 }
159 metadata
160}
161
162pub fn format_metadata(meta: &ObjectMeta) -> Metadata {
164 let mut metadata = Metadata::new(EntryMode::FILE);
165 metadata.set_content_length(meta.size);
166 if let Some(last_modified) = datetime_to_timestamp(meta.last_modified) {
167 metadata.set_last_modified(last_modified);
168 }
169 if let Some(etag) = &meta.e_tag {
170 metadata.set_etag(etag);
171 }
172 if let Some(version) = &meta.version {
173 metadata.set_version(version);
174 }
175 metadata
176}
177
178#[cfg(test)]
179mod tests {
180 use super::*;
181
182 #[test]
183 fn test_parse_op_read_suffix_range() -> Result<()> {
184 let opts = parse_op_read(&OpRead::new(), BytesRange::suffix(8))?;
185
186 assert_eq!(opts.range, Some(GetRange::Suffix(8)));
187 Ok(())
188 }
189}