1- use :: prost:: Message ;
1+ use prost:: Message ;
22use reqwest;
3+ use reqwest:: header:: CONTENT_TYPE ;
34use reqwest:: Client ;
5+ use std:: default:: Default ;
46
57use crate :: error:: VssError ;
68use crate :: types:: {
@@ -9,6 +11,8 @@ use crate::types::{
911} ;
1012use crate :: util:: retry:: { retry, RetryPolicy } ;
1113
14+ const APPLICATION_OCTET_STREAM : & str = "application/octet-stream" ;
15+
1216/// Thin-client to access a hosted instance of Versioned Storage Service (VSS).
1317/// The provided [`VssClient`] API is minimalistic and is congruent to the VSS server-side API.
1418#[ derive( Clone ) ]
@@ -45,25 +49,15 @@ impl<R: RetryPolicy<E = VssError>> VssClient<R> {
4549 retry (
4650 || async {
4751 let url = format ! ( "{}/getObject" , self . base_url) ;
48-
49- let request_body = request. encode_to_vec ( ) ;
50- let raw_response = self . client . post ( url) . body ( request_body) . send ( ) . await ?;
51- let status = raw_response. status ( ) ;
52- let payload = raw_response. bytes ( ) . await ?;
53-
54- if status. is_success ( ) {
55- let response = GetObjectResponse :: decode ( & payload[ ..] ) ?;
56-
52+ self . post_request ( request, & url) . await . and_then ( |response : GetObjectResponse | {
5753 if response. value . is_none ( ) {
58- return Err ( VssError :: InternalServerError (
54+ Err ( VssError :: InternalServerError (
5955 "VSS Server API Violation, expected value in GetObjectResponse but found none" . to_string ( ) ,
60- ) ) ;
56+ ) )
57+ } else {
58+ Ok ( response)
6159 }
62-
63- Ok ( response)
64- } else {
65- Err ( VssError :: new ( status, payload) )
66- }
60+ } )
6761 } ,
6862 & self . retry_policy ,
6963 )
@@ -78,18 +72,7 @@ impl<R: RetryPolicy<E = VssError>> VssClient<R> {
7872 retry (
7973 || async {
8074 let url = format ! ( "{}/putObjects" , self . base_url) ;
81-
82- let request_body = request. encode_to_vec ( ) ;
83- let response_raw = self . client . post ( & url) . body ( request_body) . send ( ) . await ?;
84- let status = response_raw. status ( ) ;
85- let payload = response_raw. bytes ( ) . await ?;
86-
87- if status. is_success ( ) {
88- let response = PutObjectResponse :: decode ( & payload[ ..] ) ?;
89- Ok ( response)
90- } else {
91- Err ( VssError :: new ( status, payload) )
92- }
75+ self . post_request ( request, & url) . await
9376 } ,
9477 & self . retry_policy ,
9578 )
@@ -103,18 +86,7 @@ impl<R: RetryPolicy<E = VssError>> VssClient<R> {
10386 retry (
10487 || async {
10588 let url = format ! ( "{}/deleteObject" , self . base_url) ;
106-
107- let request_body = request. encode_to_vec ( ) ;
108- let response_raw = self . client . post ( url) . body ( request_body) . send ( ) . await ?;
109- let status = response_raw. status ( ) ;
110- let payload = response_raw. bytes ( ) . await ?;
111-
112- if status. is_success ( ) {
113- let response = DeleteObjectResponse :: decode ( & payload[ ..] ) ?;
114- Ok ( response)
115- } else {
116- Err ( VssError :: new ( status, payload) )
117- }
89+ self . post_request ( request, & url) . await
11890 } ,
11991 & self . retry_policy ,
12092 )
@@ -130,21 +102,30 @@ impl<R: RetryPolicy<E = VssError>> VssClient<R> {
130102 retry (
131103 || async {
132104 let url = format ! ( "{}/listKeyVersions" , self . base_url) ;
133-
134- let request_body = request. encode_to_vec ( ) ;
135- let response_raw = self . client . post ( url) . body ( request_body) . send ( ) . await ?;
136- let status = response_raw. status ( ) ;
137- let payload = response_raw. bytes ( ) . await ?;
138-
139- if status. is_success ( ) {
140- let response = ListKeyVersionsResponse :: decode ( & payload[ ..] ) ?;
141- Ok ( response)
142- } else {
143- Err ( VssError :: new ( status, payload) )
144- }
105+ self . post_request ( request, & url) . await
145106 } ,
146107 & self . retry_policy ,
147108 )
148109 . await
149110 }
111+
112+ async fn post_request < Rq : Message , Rs : Message + Default > ( & self , request : & Rq , url : & str ) -> Result < Rs , VssError > {
113+ let request_body = request. encode_to_vec ( ) ;
114+ let response_raw = self
115+ . client
116+ . post ( url)
117+ . header ( CONTENT_TYPE , APPLICATION_OCTET_STREAM )
118+ . body ( request_body)
119+ . send ( )
120+ . await ?;
121+ let status = response_raw. status ( ) ;
122+ let payload = response_raw. bytes ( ) . await ?;
123+
124+ if status. is_success ( ) {
125+ let response = Rs :: decode ( & payload[ ..] ) ?;
126+ Ok ( response)
127+ } else {
128+ Err ( VssError :: new ( status, payload) )
129+ }
130+ }
150131}
0 commit comments