tame_gcs/v1/objects/
download.rs1use crate::{
2 common::{Conditionals, Projection, StandardQueryParameters},
3 error::Error,
4 response::ApiResponse,
5 types::ObjectIdentifier,
6};
7use std::io;
8
9#[derive(Default, Serialize)]
10#[serde(rename_all = "camelCase")]
11pub struct DownloadObjectOptional<'a> {
12 #[serde(flatten)]
13 pub standard_params: StandardQueryParameters<'a>,
14 #[serde(skip_serializing_if = "Option::is_none")]
17 pub generation: Option<i64>,
18 #[serde(flatten)]
19 pub conditionals: Conditionals,
20 #[serde(skip_serializing_if = "Option::is_none")]
23 pub projection: Option<Projection>,
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub user_project: Option<&'a str>,
27}
28
29pub struct DownloadObjectResponse {
30 buffer: bytes::Bytes,
31}
32
33impl DownloadObjectResponse {
34 pub fn consume(self) -> bytes::Bytes {
35 self.buffer
36 }
37}
38
39impl ApiResponse<bytes::Bytes> for DownloadObjectResponse {}
40
41impl TryFrom<http::Response<bytes::Bytes>> for DownloadObjectResponse {
42 type Error = Error;
43
44 fn try_from(response: http::Response<bytes::Bytes>) -> Result<Self, Self::Error> {
45 let (_parts, body) = response.into_parts();
46
47 Ok(Self { buffer: body })
48 }
49}
50
51impl std::ops::Deref for DownloadObjectResponse {
52 type Target = [u8];
53
54 fn deref(&self) -> &[u8] {
55 self.buffer.as_ref()
56 }
57}
58
59impl io::Read for DownloadObjectResponse {
60 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
61 use bytes::Buf;
62
63 let buf_len = std::cmp::min(self.buffer.len(), buf.len());
64 let mut slice = self.buffer.split_to(buf_len);
65 slice.copy_to_slice(&mut buf[..buf_len]);
66
67 Ok(buf_len)
68 }
69}
70
71impl super::Object {
72 pub fn download<'a, OID>(
78 &self,
79 id: &OID,
80 optional: Option<DownloadObjectOptional<'_>>,
81 ) -> Result<http::Request<std::io::Empty>, Error>
82 where
83 OID: ObjectIdentifier<'a> + ?Sized,
84 {
85 let mut uri = crate::__make_obj_url!(
86 "https://{}/storage/v1/b/{}/o/{}?alt=media",
87 self.authority,
88 id
89 );
90
91 let query = optional.unwrap_or_default();
92 let query_params = serde_urlencoded::to_string(query)?;
93 if !query_params.is_empty() {
94 uri.push('&');
95 uri.push_str(&query_params);
96 }
97
98 let req_builder = http::Request::builder();
99
100 Ok(req_builder.method("GET").uri(uri).body(std::io::empty())?)
101 }
102}