opendal/services/dropbox/
writer.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::sync::Arc;
19
20use bytes::Buf;
21use http::StatusCode;
22
23use super::core::{DropboxCore, DropboxMetadataResponse};
24use super::error::parse_error;
25use crate::raw::*;
26use crate::*;
27
28pub struct DropboxWriter {
29    core: Arc<DropboxCore>,
30    op: OpWrite,
31    path: String,
32}
33
34impl DropboxWriter {
35    pub fn new(core: Arc<DropboxCore>, op: OpWrite, path: String) -> Self {
36        DropboxWriter { core, op, path }
37    }
38
39    fn parse_metadata(decoded_response: DropboxMetadataResponse) -> Result<Metadata> {
40        let mut metadata = Metadata::default();
41
42        if let Some(size) = decoded_response.size {
43            metadata.set_content_length(size);
44        }
45
46        if let Some(content_hash) = decoded_response.content_hash {
47            metadata.set_etag(&content_hash);
48        }
49
50        if let Some(rev) = decoded_response.rev {
51            metadata.set_version(&rev);
52        }
53
54        if let Some(server_modified) = decoded_response.server_modified {
55            let date_utc = server_modified.parse::<Timestamp>()?;
56            metadata.set_last_modified(date_utc);
57        } else {
58            let date_utc = decoded_response.client_modified.parse::<Timestamp>()?;
59            metadata.set_last_modified(date_utc);
60        }
61
62        Ok(metadata)
63    }
64}
65
66impl oio::OneShotWrite for DropboxWriter {
67    async fn write_once(&self, bs: Buffer) -> Result<Metadata> {
68        let resp = self
69            .core
70            .dropbox_update(&self.path, Some(bs.len()), &self.op, bs)
71            .await?;
72        let status = resp.status();
73        match status {
74            StatusCode::OK => {
75                let bytes = resp.into_body();
76                let decoded_response: DropboxMetadataResponse =
77                    serde_json::from_reader(bytes.reader()).map_err(new_json_deserialize_error)?;
78                let metadata = DropboxWriter::parse_metadata(decoded_response)?;
79                Ok(metadata)
80            }
81            _ => Err(parse_error(resp)),
82        }
83    }
84}