@@ -163,15 +163,14 @@ impl Format {
163163 let href = href. into ( ) ;
164164 match href. clone ( ) . realize ( ) {
165165 RealizedHref :: Url ( url) => {
166- use object_store:: ObjectStore ;
167-
168166 let ( object_store, path) = parse_url_opts ( & url, options) ?;
169- tracing:: debug!( "getting {self} from {url} with object store" ) ;
170- let get_result = object_store. get ( & path) . await . map_err ( |err| Error :: Get {
171- href,
172- message : err. to_string ( ) ,
173- } ) ?;
174- let mut value: T = self . from_bytes ( get_result. bytes ( ) . await ?) ?;
167+ let mut value: T =
168+ self . get_store ( object_store. into ( ) , path)
169+ . await
170+ . map_err ( |err| Error :: Get {
171+ href,
172+ message : err. to_string ( ) ,
173+ } ) ?;
175174 * value. self_href_mut ( ) = Some ( Href :: Url ( url) ) ;
176175 Ok ( value)
177176 }
@@ -188,6 +187,23 @@ impl Format {
188187 }
189188 }
190189
190+ /// Gets a STAC value from an object store.
191+ #[ cfg( feature = "object-store" ) ]
192+ pub async fn get_store < T > (
193+ & self ,
194+ object_store : std:: sync:: Arc < dyn object_store:: ObjectStore > ,
195+ path : impl Into < object_store:: path:: Path > ,
196+ ) -> Result < T >
197+ where
198+ T : SelfHref + FromJson + FromNdjson + FromGeoparquet ,
199+ {
200+ let path = path. into ( ) ;
201+ tracing:: debug!( "getting {self} from {path} with object store" ) ;
202+ let get_result = object_store. get ( & path) . await ?;
203+ let value: T = self . from_bytes ( get_result. bytes ( ) . await ?) ?;
204+ Ok ( value)
205+ }
206+
191207 /// Writes a STAC value to the provided path.
192208 ///
193209 /// # Examples
@@ -257,17 +273,31 @@ impl Format {
257273 {
258274 let href = href. to_string ( ) ;
259275 if let Ok ( url) = url:: Url :: parse ( & href) {
260- use object_store:: ObjectStore ;
261-
262276 let ( object_store, path) = parse_url_opts ( & url, options) ?;
263- let bytes = self . into_vec ( value) ? ;
264- let put_result = object_store . put ( & path , bytes . into ( ) ) . await ? ;
265- Ok ( Some ( put_result ) )
277+ self . put_store ( object_store . into ( ) , path , value)
278+ . await
279+ . map ( Some )
266280 } else {
267281 self . write ( href, value) . map ( |_| None )
268282 }
269283 }
270284
285+ /// Puts a STAC value into an object store.
286+ #[ cfg( feature = "object-store" ) ]
287+ pub async fn put_store < T > (
288+ & self ,
289+ object_store : std:: sync:: Arc < dyn object_store:: ObjectStore > ,
290+ path : impl Into < object_store:: path:: Path > ,
291+ value : T ,
292+ ) -> Result < object_store:: PutResult >
293+ where
294+ T : ToJson + ToNdjson + IntoGeoparquet ,
295+ {
296+ let bytes = self . into_vec ( value) ?;
297+ let put_result = object_store. put ( & path. into ( ) , bytes. into ( ) ) . await ?;
298+ Ok ( put_result)
299+ }
300+
271301 /// Returns the default JSON format (compact).
272302 pub fn json ( ) -> Format {
273303 Format :: Json ( false )
@@ -384,6 +414,7 @@ impl FromStr for Format {
384414#[ cfg( test) ]
385415mod tests {
386416 use super :: Format ;
417+ use crate :: Item ;
387418 use crate :: geoparquet:: Compression ;
388419
389420 #[ test]
@@ -425,4 +456,33 @@ mod tests {
425456 Format :: infer_from_href( "out.parquet" ) . unwrap( )
426457 ) ;
427458 }
459+
460+ #[ tokio:: test]
461+ #[ cfg( feature = "object-store" ) ]
462+ async fn prefix_store_read ( ) {
463+ use std:: sync:: Arc ;
464+
465+ let object_store =
466+ object_store:: local:: LocalFileSystem :: new_with_prefix ( "examples" ) . unwrap ( ) ;
467+ let _: Item = Format :: json ( )
468+ . get_store ( Arc :: new ( object_store) , "simple-item.json" )
469+ . await
470+ . unwrap ( ) ;
471+ }
472+
473+ #[ tokio:: test]
474+ #[ cfg( feature = "object-store" ) ]
475+ async fn store_write ( ) {
476+ use object_store:: ObjectStore ;
477+ use std:: sync:: Arc ;
478+
479+ let object_store = Arc :: new ( object_store:: memory:: InMemory :: new ( ) ) ;
480+ let item = Item :: new ( "an-id" ) ;
481+ let _ = Format :: json ( )
482+ . put_store ( object_store. clone ( ) , "item.json" , item)
483+ . await
484+ . unwrap ( ) ;
485+ let get_result = object_store. get ( & "item.json" . into ( ) ) . await . unwrap ( ) ;
486+ let _: Item = serde_json:: from_slice ( & get_result. bytes ( ) . await . unwrap ( ) ) . unwrap ( ) ;
487+ }
428488}
0 commit comments