1717mod decompress;
1818
1919use azure_core:: error:: { Error , ErrorKind , Result , ResultExt } ;
20- use azure_core:: headers:: { self , HeaderValue } ;
21- use azure_core:: { Method , Request , Url } ;
20+ use azure_core:: http :: headers:: { self , HeaderValue } ;
21+ use azure_core:: http :: { Method , Request , Url } ;
2222use serde:: Deserialize ;
2323use std:: collections:: HashMap ;
2424use std:: io:: Write ;
@@ -88,15 +88,15 @@ pub struct Manifest {
8888pub struct Client {
8989 credential : crate :: Credential ,
9090 scopes : Vec < String > ,
91- pipeline : azure_core:: Pipeline ,
91+ pipeline : azure_core:: http :: Pipeline ,
9292}
9393
9494/// Builder for creating an artifacts download [`Client`].
9595#[ derive( Clone ) ]
9696pub struct ClientBuilder {
9797 credential : crate :: Credential ,
9898 scopes : Option < Vec < String > > ,
99- options : azure_core:: ClientOptions ,
99+ options : azure_core:: http :: ClientOptions ,
100100}
101101
102102impl ClientBuilder {
@@ -106,7 +106,7 @@ impl ClientBuilder {
106106 Self {
107107 credential,
108108 scopes : None ,
109- options : azure_core:: ClientOptions :: default ( ) ,
109+ options : azure_core:: http :: ClientOptions :: default ( ) ,
110110 }
111111 }
112112
@@ -119,15 +119,15 @@ impl ClientBuilder {
119119
120120 /// Set the retry options.
121121 #[ must_use]
122- pub fn retry ( mut self , retry : impl Into < azure_core:: RetryOptions > ) -> Self {
123- self . options = self . options . retry ( retry ) ;
122+ pub fn retry ( mut self , retry : impl Into < azure_core:: http :: RetryOptions > ) -> Self {
123+ self . options . retry = retry. into ( ) ;
124124 self
125125 }
126126
127127 /// Set the transport options.
128128 #[ must_use]
129- pub fn transport ( mut self , transport : impl Into < azure_core:: TransportOptions > ) -> Self {
130- self . options = self . options . transport ( transport) ;
129+ pub fn transport ( mut self , transport : impl Into < azure_core:: http :: Transport > ) -> Self {
130+ self . options . transport = Some ( transport. into ( ) ) ;
131131 self
132132 }
133133
@@ -136,12 +136,13 @@ impl ClientBuilder {
136136 let scopes = self
137137 . scopes
138138 . unwrap_or_else ( || vec ! [ crate :: ADO_SCOPE . to_string( ) ] ) ;
139- let pipeline = azure_core:: Pipeline :: new (
139+ let pipeline = azure_core:: http :: Pipeline :: new (
140140 option_env ! ( "CARGO_PKG_NAME" ) ,
141141 option_env ! ( "CARGO_PKG_VERSION" ) ,
142142 self . options ,
143143 Vec :: new ( ) ,
144144 Vec :: new ( ) ,
145+ None ,
145146 ) ;
146147 Client {
147148 credential : self . credential ,
@@ -164,13 +165,13 @@ impl Client {
164165 self . credential
165166 . http_authorization_header ( & scopes)
166167 . await ?
167- . ok_or_else ( || Error :: message ( ErrorKind :: Credential , "No credential configured" ) )
168+ . ok_or_else ( || Error :: with_message ( ErrorKind :: Credential , "No credential configured" ) )
168169 }
169170
170171 /// Send a request through the pipeline.
171- async fn send ( & self , request : & mut Request ) -> Result < azure_core:: Response > {
172- let context = azure_core:: Context :: default ( ) ;
173- self . pipeline . send ( & context, request) . await
172+ async fn send ( & self , request : & mut Request ) -> Result < azure_core:: http :: RawResponse > {
173+ let context = azure_core:: http :: Context :: default ( ) ;
174+ self . pipeline . send ( & context, request, None ) . await
174175 }
175176
176177 /// Send an authenticated GET request and parse the JSON response.
@@ -183,17 +184,17 @@ impl Client {
183184 HeaderValue :: from ( "application/json; api-version=7.1-preview.1" ) ,
184185 ) ;
185186 req. insert_header ( "x-tfs-fedauthredirect" , HeaderValue :: from ( "Suppress" ) ) ;
186- req. set_body ( azure_core:: EMPTY_BODY ) ;
187+ req. set_body ( azure_core:: Bytes :: new ( ) ) ;
187188
188189 let resp = self . send ( & mut req) . await ?;
189- let bytes = resp. into_body ( ) . collect ( ) . await ? ;
190- serde_json:: from_slice ( & bytes ) . map_err ( |e| {
191- Error :: full (
190+ let body = resp. into_body ( ) ;
191+ serde_json:: from_slice ( & body ) . map_err ( |e| {
192+ Error :: with_error (
192193 ErrorKind :: DataConversion ,
193194 e,
194195 format ! (
195196 "Failed to deserialize response:\n {}" ,
196- String :: from_utf8_lossy( & bytes )
197+ String :: from_utf8_lossy( & body )
197198 ) ,
198199 )
199200 } )
@@ -202,10 +203,10 @@ impl Client {
202203 /// Send an unauthenticated GET request and return the raw bytes.
203204 async fn get_bytes ( & self , url : Url ) -> Result < Vec < u8 > > {
204205 let mut req = Request :: new ( url, Method :: Get ) ;
205- req. set_body ( azure_core:: EMPTY_BODY ) ;
206+ req. set_body ( azure_core:: Bytes :: new ( ) ) ;
206207 let resp = self . send ( & mut req) . await ?;
207- let bytes = resp. into_body ( ) . collect ( ) . await ? ;
208- Ok ( bytes . to_vec ( ) )
208+ let body = resp. into_body ( ) ;
209+ Ok ( body . to_vec ( ) )
209210 }
210211
211212 // --- Service discovery ---
@@ -217,7 +218,7 @@ impl Client {
217218 "https://dev.azure.com/{}/_apis/ResourceAreas" ,
218219 organization
219220 ) )
220- . context ( ErrorKind :: DataConversion , "invalid organization URL" ) ?;
221+ . with_context ( ErrorKind :: DataConversion , "invalid organization URL" ) ?;
221222
222223 let areas: ResourceAreasResponse = self . get_json ( url) . await ?;
223224 let map: HashMap < String , String > = areas
@@ -240,7 +241,7 @@ impl Client {
240241 /// Find the blob/dedup service URL from discovered services.
241242 pub fn find_blob_url ( services : & HashMap < String , String > ) -> Result < String > {
242243 services. get ( "dedup" ) . cloned ( ) . ok_or_else ( || {
243- Error :: message (
244+ Error :: with_message (
244245 ErrorKind :: Other ,
245246 "Could not find 'dedup' service in ResourceAreas" ,
246247 )
@@ -266,7 +267,7 @@ impl Client {
266267 name,
267268 version,
268269 ) )
269- . context ( ErrorKind :: DataConversion , "invalid package metadata URL" ) ?;
270+ . with_context ( ErrorKind :: DataConversion , "invalid package metadata URL" ) ?;
270271
271272 url. query_pairs_mut ( ) . append_pair ( "intent" , "Download" ) ;
272273 self . get_json ( url) . await
@@ -284,7 +285,7 @@ impl Client {
284285 "{}/_apis/dedup/urls" ,
285286 blob_service_url. trim_end_matches( '/' )
286287 ) )
287- . context ( ErrorKind :: DataConversion , "invalid dedup URL" ) ?;
288+ . with_context ( ErrorKind :: DataConversion , "invalid dedup URL" ) ?;
288289
289290 url. query_pairs_mut ( ) . append_pair ( "allowEdge" , "true" ) ;
290291
@@ -300,13 +301,13 @@ impl Client {
300301 HeaderValue :: from ( "application/json; api-version=1.0" ) ,
301302 ) ;
302303 req. insert_header ( "x-tfs-fedauthredirect" , HeaderValue :: from ( "Suppress" ) ) ;
303- let body = azure_core:: to_json ( blob_ids) ?;
304+ let body = azure_core:: json :: to_json ( blob_ids) ?;
304305 req. set_body ( body) ;
305306
306307 let resp = self . send ( & mut req) . await ?;
307- let bytes = resp. into_body ( ) . collect ( ) . await ? ;
308- serde_json:: from_slice ( & bytes ) . map_err ( |e| {
309- Error :: full (
308+ let body = resp. into_body ( ) ;
309+ serde_json:: from_slice ( & body ) . map_err ( |e| {
310+ Error :: with_error (
310311 ErrorKind :: DataConversion ,
311312 e,
312313 "Failed to parse blob URL response" ,
@@ -317,7 +318,7 @@ impl Client {
317318 /// Download a blob from a SAS URL (no auth required).
318319 pub async fn download_blob ( & self , url : & str ) -> Result < Vec < u8 > > {
319320 let parsed =
320- Url :: parse ( url) . context ( ErrorKind :: DataConversion , "invalid blob download URL" ) ?;
321+ Url :: parse ( url) . with_context ( ErrorKind :: DataConversion , "invalid blob download URL" ) ?;
321322 self . get_bytes ( parsed) . await
322323 }
323324
@@ -326,7 +327,7 @@ impl Client {
326327 /// Parse the dedup manifest blob (JSON) to extract file entries.
327328 pub fn parse_manifest ( data : & [ u8 ] ) -> Result < Manifest > {
328329 serde_json:: from_slice ( data) . map_err ( |e| {
329- Error :: full (
330+ Error :: with_error (
330331 ErrorKind :: DataConversion ,
331332 e,
332333 "Failed to parse manifest JSON" ,
@@ -350,7 +351,7 @@ impl Client {
350351 const ENTRY_SIZE : usize = METADATA_SIZE + HASH_SIZE ;
351352
352353 if data. len ( ) < HEADER_SIZE + ENTRY_SIZE {
353- return Err ( Error :: message (
354+ return Err ( Error :: with_message (
354355 ErrorKind :: DataConversion ,
355356 format ! (
356357 "Dedup node blob too small: {} bytes (minimum {})" ,
@@ -362,7 +363,7 @@ impl Client {
362363
363364 let data_portion = data. len ( ) - HEADER_SIZE ;
364365 if data_portion % ENTRY_SIZE != 0 {
365- return Err ( Error :: message (
366+ return Err ( Error :: with_message (
366367 ErrorKind :: DataConversion ,
367368 format ! (
368369 "Dedup node blob has unexpected size: {} bytes \
@@ -385,7 +386,7 @@ impl Client {
385386 }
386387
387388 if chunk_ids. is_empty ( ) {
388- return Err ( Error :: message (
389+ return Err ( Error :: with_message (
389390 ErrorKind :: DataConversion ,
390391 format ! (
391392 "No chunk references found in dedup node blob ({} bytes)" ,
@@ -426,14 +427,14 @@ impl Client {
426427 . resolve_blob_urls ( & blob_service_url, & [ metadata. manifest_id . clone ( ) ] )
427428 . await ?;
428429 let manifest_url = manifest_urls. get ( & metadata. manifest_id ) . ok_or_else ( || {
429- Error :: message ( ErrorKind :: Other , "Manifest URL not found in response" )
430+ Error :: with_message ( ErrorKind :: Other , "Manifest URL not found in response" )
430431 } ) ?;
431432 let manifest_data = self . download_blob ( manifest_url) . await ?;
432433 let manifest = Self :: parse_manifest ( & manifest_data) ?;
433434
434435 // Step 4: Create output directory
435436 std:: fs:: create_dir_all ( output_path) . map_err ( |e| {
436- Error :: full (
437+ Error :: with_error (
437438 ErrorKind :: Io ,
438439 e,
439440 format ! ( "Failed to create output directory: {:?}" , output_path) ,
@@ -447,7 +448,7 @@ impl Client {
447448 . await ?;
448449 let file_root_url = file_root_urls
449450 . get ( & item. blob . id )
450- . ok_or_else ( || Error :: message ( ErrorKind :: Other , "File root URL not found" ) ) ?;
451+ . ok_or_else ( || Error :: with_message ( ErrorKind :: Other , "File root URL not found" ) ) ?;
451452 let file_root_data = self . download_blob ( file_root_url) . await ?;
452453
453454 let is_node = item. blob . id . ends_with ( "02" ) ;
@@ -461,7 +462,7 @@ impl Client {
461462 let mut file_data = Vec :: with_capacity ( item. blob . size as usize ) ;
462463 for chunk_id in & chunk_ids {
463464 let chunk_url = chunk_urls. get ( chunk_id) . ok_or_else ( || {
464- Error :: message (
465+ Error :: with_message (
465466 ErrorKind :: Other ,
466467 format ! ( "Chunk URL not found for {}" , chunk_id) ,
467468 )
@@ -479,22 +480,22 @@ impl Client {
479480 let file_path = output_path. join ( relative_path) ;
480481 if let Some ( parent) = file_path. parent ( ) {
481482 std:: fs:: create_dir_all ( parent) . map_err ( |e| {
482- Error :: full (
483+ Error :: with_error (
483484 ErrorKind :: Io ,
484485 e,
485486 format ! ( "Failed to create directory: {:?}" , parent) ,
486487 )
487488 } ) ?;
488489 }
489490 let mut file = std:: fs:: File :: create ( & file_path) . map_err ( |e| {
490- Error :: full (
491+ Error :: with_error (
491492 ErrorKind :: Io ,
492493 e,
493494 format ! ( "Failed to create file: {:?}" , file_path) ,
494495 )
495496 } ) ?;
496497 file. write_all ( & file_data)
497- . map_err ( |e| Error :: full ( ErrorKind :: Io , e, "Failed to write file data" ) ) ?;
498+ . map_err ( |e| Error :: with_error ( ErrorKind :: Io , e, "Failed to write file data" ) ) ?;
498499 }
499500
500501 Ok ( metadata)
0 commit comments