From 5171f06ad983ea99bcd28f2a78dc52a1d525ca06 Mon Sep 17 00:00:00 2001 From: Thomas Tanon Date: Wed, 3 Jun 2026 15:12:47 +0200 Subject: [PATCH] Implement Signer on PrefixStore Small convenience feature --- src/prefix.rs | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/prefix.rs b/src/prefix.rs index b6e9137f..46cd6816 100644 --- a/src/prefix.rs +++ b/src/prefix.rs @@ -22,6 +22,8 @@ use std::ops::Range; use crate::multipart::{MultipartStore, PartId}; use crate::path::Path; +#[cfg(feature = "cloud")] +use crate::signer::Signer; use crate::{ CopyOptions, GetOptions, GetResult, ListResult, MultipartId, MultipartUpload, ObjectMeta, ObjectStore, PutMultipartOptions, PutOptions, PutPayload, PutResult, RenameOptions, Result, @@ -234,6 +236,36 @@ impl MultipartStore for PrefixStore { } } +#[cfg(feature = "cloud")] +#[async_trait::async_trait] +impl Signer for PrefixStore { + async fn signed_url( + &self, + method: http::Method, + path: &Path, + expires_in: std::time::Duration, + ) -> Result { + self.inner + .signed_url(method, &self.full_path(path), expires_in) + .await + } + + async fn signed_urls( + &self, + method: http::Method, + paths: &[Path], + expires_in: std::time::Duration, + ) -> Result> { + self.inner + .signed_urls( + method, + &paths.iter().map(|p| self.full_path(p)).collect::>(), + expires_in, + ) + .await + } +} + #[cfg(not(target_arch = "wasm32"))] #[cfg(test)] mod tests { @@ -363,4 +395,46 @@ mod tests { multipart_out_of_order(&store).await; multipart_race_condition(&store, true).await; } + + #[cfg(feature = "cloud")] + #[tokio::test] + async fn signer() { + #[derive(Debug)] + struct Foo; + + #[async_trait::async_trait] + impl Signer for Foo { + async fn signed_url( + &self, + method: http::Method, + path: &Path, + _expires_in: std::time::Duration, + ) -> Result { + Ok(url::Url::parse(&format!("ex:{path}?method={method}")).unwrap()) + } + } + + assert_eq!( + PrefixStore::new(Foo, "prefix") + .signed_url( + http::Method::GET, + &"foo".into(), + std::time::Duration::from_secs(1) + ) + .await + .unwrap(), + url::Url::parse("ex:prefix/foo?method=GET").unwrap() + ); + assert_eq!( + PrefixStore::new(Foo, "prefix") + .signed_urls( + http::Method::GET, + &["foo".into()], + std::time::Duration::from_secs(1) + ) + .await + .unwrap(), + vec![url::Url::parse("ex:prefix/foo?method=GET").unwrap()] + ); + } }