opendal/services/dropbox/
writer.rs1use 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}