Skip to content

Commit

Permalink
Add AsyncReader::try_get_tile.
Browse files Browse the repository at this point in the history
* Exposes the error when fetching a tile (to ensure we can distinguish between missing tiles and upstream errors).
* Adds a `TileNotFound` error case.
* Bumps version to 0.8.0.
  • Loading branch information
lseelenbinder committed Apr 10, 2024
1 parent a8f86e4 commit 25dce42
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 7 deletions.
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pmtiles"
version = "0.7.1"
version = "0.8.0"
edition = "2021"
authors = ["Luke Seelenbinder <[email protected]>"]
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -39,7 +39,7 @@ async-trait = "0.1"
bytes = "1"
fmmap = { version = "0.3", default-features = false, optional = true }
hilbert_2d = "1"
reqwest = { version = "0.11", default-features = false, optional = true }
reqwest = { version = "0.12.3", default-features = false, optional = true }
rust-s3 = { version = "0.33.0", optional = true, default-features = false, features = ["fail-on-err"] }
serde = { version = "1", optional = true }
serde_json = { version = "1", optional = true }
Expand All @@ -51,7 +51,7 @@ varint-rs = "2"
[dev-dependencies]
flate2 = "1"
fmmap = { version = "0.3", features = ["tokio-async"] }
reqwest = { version = "0.11", features = ["rustls-tls-webpki-roots"] }
reqwest = { version = "0.12.3", features = ["rustls-tls-webpki-roots"] }
tokio = { version = "1", features = ["test-util", "macros", "rt"] }

[package.metadata.docs.rs]
Expand Down
19 changes: 15 additions & 4 deletions src/async_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,22 @@ impl<B: AsyncBackend + Sync + Send, C: DirectoryCache + Sync + Send> AsyncPmTile

/// Fetches tile bytes from the archive.
pub async fn get_tile(&self, z: u8, x: u64, y: u64) -> Option<Bytes> {
self.try_get_tile(z, x, y).await.ok()
}

/// Fetches tile bytes from the archive, exposing the underlying error
/// (if any).
pub async fn try_get_tile(&self, z: u8, x: u64, y: u64) -> PmtResult<Bytes> {
let tile_id = tile_id(z, x, y);
let entry = self.find_tile_entry(tile_id).await?;
let entry = self
.find_tile_entry(tile_id)
.await
.ok_or(PmtError::TileNotFound)?;

let offset = (self.header.data_offset + entry.offset) as _;
let length = entry.length as _;
let data = self.backend.read_exact(offset, length).await.ok()?;

Some(data)
self.backend.read_exact(offset, length).await
}

/// Access header information.
Expand Down Expand Up @@ -220,7 +228,7 @@ pub trait AsyncBackend {
mod tests {
use super::AsyncPmTilesReader;
use crate::tests::{RASTER_FILE, VECTOR_FILE};
use crate::MmapBackend;
use crate::{MmapBackend, PmtError, PmtResult};

#[tokio::test]
async fn open_sanity_check() {
Expand Down Expand Up @@ -266,6 +274,9 @@ mod tests {

let tile = tiles.get_tile(6, 31, 23).await;
assert!(tile.is_none());

let tile = tiles.try_get_tile(6, 31, 23).await;
assert!(matches!(tile, PmtResult::Err(PmtError::TileNotFound)));
}

#[tokio::test]
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ pub enum PmtError {
#[cfg(feature = "__async-s3")]
#[error(transparent)]
S3(#[from] s3::error::S3Error),
#[error("Tile was not found in the PMTiles archive.")]
TileNotFound,
}

0 comments on commit 25dce42

Please sign in to comment.