-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for rust-s3
backend.
#30
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good! A few minor nits, and we need to re-export the underlying s3 crate somehow, but it conflicts with the s3.rs
file. I would recommend NOT exporting the s3
, http
, and mmap
namespaces. Instead, publish their content directly.
// --- this is lib.rs ---
pub use s3; // re-export s3 crate as pmtiles::s3
mod s3_backend;
pub use s3_backend S3Backend;
mod http;
pub use http::HttpBackend;
Cargo.toml
Outdated
@@ -13,6 +13,8 @@ categories = ["science::geo"] | |||
[features] | |||
default = [] | |||
http-async = ["dep:tokio", "dep:reqwest"] | |||
s3-async = ["dep:tokio", "dep:rust-s3", "rust-s3/tokio-native-tls"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe call it s3-async-native
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. Done.
src/error.rs
Outdated
@@ -32,6 +32,9 @@ pub enum PmtError { | |||
#[cfg(feature = "http-async")] | |||
#[error("{0}")] | |||
Http(#[from] PmtHttpError), | |||
#[cfg(any(feature = "s3-async-rustls", feature = "s3-async"))] | |||
#[error("{0}")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And above as well
#[error("{0}")] | |
#[error(transparent)] |
src/s3.rs
Outdated
let response_bytes = response.bytes(); | ||
|
||
if response_bytes.len() > length { | ||
Err(crate::error::PmtS3Error::ResponseBodyTooLong(response_bytes.len(), length).into()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shorten it with use ...
at the top?
Do we want to re-export |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to re-export
s3
or allow users to bring their own (as we do withreqwest
)? I tried really hard to make this TLS implementation agnostic, butrust-s3
doesn't build properly when it doesn't have a concrete credentials type.
There is really no such thing as "bring your own" here. If we do not re-export a dependency, users must play the magic game of "match my dependencies with the dependencies of my dependency" - i.e. user must use the same version of reqwest
lib as used by the API of the pmtiles crate. This is an antipattern because it will only work if Cargo ends up using identical version of reqwest for both. Otherwise, it might not compile. That's why sometimes people opt to use reqwest = "*"
- which again is an antipattern, but they have to do it to match the API of a crate they want to use.
Instead, I think a much safer way is to either (1) ensure all pmtiles crate API only uses standard Rust types (or types declared in the pmtiles crate itself), or (2) re-export all 3rd party types together with all the other stuff related to those types - i.e. re-export reqwest
and s3
sub-dependencies in their own namespaces like pmtiles::reqwest::*
and pmtiles::s3::*
.
Also, a few inline comments.
src/error.rs
Outdated
|
||
#[cfg(any(feature = "s3-async-rustls", feature = "s3-async-native"))] | ||
#[derive(Debug, Error)] | ||
pub enum PmtS3Error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not flatten all errors - just add these to PmtError
with a conditional #[cfg(...)]
? I am not sure there is much value in having multi-level errors here, is there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. Done.
src/backend/mod.rs
Outdated
#[cfg(any(feature = "s3-async-native", feature = "s3-async-rustls"))] | ||
pub(crate) mod s3; | ||
|
||
#[cfg(feature = "http-async")] | ||
pub(crate) mod http; | ||
|
||
#[cfg(feature = "mmap-async-tokio")] | ||
pub(crate) mod mmap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't really need to control the access here - enough to say pub mod s3
- that shouldn't make it public on the crate level, as long as you do not use pub mod backend
in lib.rs
.
That said, mod.rs offer a better way to compartmentalize things - you don't need to expose internals of the backend
mod to the rest of the crate - I think it is cleaner to expose just the needed structs (up to you though) - you can also just remove the (crate)
and keep sub-namespaces.
#[cfg(any(feature = "s3-async-native", feature = "s3-async-rustls"))] | |
pub(crate) mod s3; | |
#[cfg(feature = "http-async")] | |
pub(crate) mod http; | |
#[cfg(feature = "mmap-async-tokio")] | |
pub(crate) mod mmap; | |
#[cfg(any(feature = "s3-async-native", feature = "s3-async-rustls"))] | |
mod s3; | |
#[cfg(any(feature = "s3-async-native", feature = "s3-async-rustls"))] | |
pub use s3::S3Backend; | |
#[cfg(feature = "http-async")] | |
mod http; | |
#[cfg(feature = "http-async")] | |
pub use http::HttpBackend; | |
#[cfg(feature = "mmap-async-tokio")] | |
mod mmap; | |
#[cfg(feature = "mmap-async-tokio")] | |
pub use mmap::MmapBackend; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, cleaned up.
Fair enough. And users can always bring their own, if they want—just because we're nice and re-export doesn't mean users will use the exports. 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!!
Fixes #11 and could be used to address maplibre/martin#1125.