diff --git a/src/async_reader.rs b/src/async_reader.rs index 48c56bd..c9e843a 100644 --- a/src/async_reader.rs +++ b/src/async_reader.rs @@ -17,7 +17,7 @@ use crate::cache::DirCacheResult; #[cfg(any(feature = "http-async", feature = "mmap-async-tokio"))] use crate::cache::{DirectoryCache, NoCache}; use crate::directory::{DirEntry, Directory}; -use crate::error::PmtError; +use crate::error::{PmtError, PmtResult}; use crate::header::{HEADER_SIZE, MAX_INITIAL_BYTES}; #[cfg(feature = "http-async")] use crate::http::HttpBackend; @@ -37,7 +37,7 @@ impl AsyncPmTilesReader { /// Creates a new reader from a specified source and validates the provided `PMTiles` archive is valid. /// /// Note: Prefer using `new_with_*` methods. - pub async fn try_from_source(backend: B) -> Result { + pub async fn try_from_source(backend: B) -> PmtResult { Self::try_from_cached_source(backend, NoCache).await } } @@ -46,7 +46,7 @@ impl AsyncPmTile /// Creates a new cached reader from a specified source and validates the provided `PMTiles` archive is valid. /// /// Note: Prefer using `new_with_*` methods. - pub async fn try_from_cached_source(backend: B, cache: C) -> Result { + pub async fn try_from_cached_source(backend: B, cache: C) -> PmtResult { // Read the first 127 and up to 16,384 bytes to ensure we can initialize the header and root directory. let mut initial_bytes = backend.read(0, MAX_INITIAL_BYTES).await?; if initial_bytes.len() < HEADER_SIZE { @@ -91,7 +91,7 @@ impl AsyncPmTile /// /// Note: by spec, this should be valid JSON. This method currently returns a [String]. /// This may change in the future. - pub async fn get_metadata(&self) -> Result { + pub async fn get_metadata(&self) -> PmtResult { let offset = self.header.metadata_offset as _; let length = self.header.metadata_length as _; let metadata = self.backend.read_exact(offset, length).await?; @@ -103,10 +103,7 @@ impl AsyncPmTile } #[cfg(feature = "tilejson")] - pub async fn parse_tilejson( - &self, - sources: Vec, - ) -> Result { + pub async fn parse_tilejson(&self, sources: Vec) -> PmtResult { use serde_json::Value; let meta = self.get_metadata().await?; @@ -190,7 +187,7 @@ impl AsyncPmTile entry } - async fn read_directory(&self, offset: usize, length: usize) -> Result { + async fn read_directory(&self, offset: usize, length: usize) -> PmtResult { let data = self.backend.read_exact(offset, length).await?; Self::read_compressed_directory(self.header.internal_compression, data).await } @@ -198,12 +195,12 @@ impl AsyncPmTile async fn read_compressed_directory( compression: Compression, bytes: Bytes, - ) -> Result { + ) -> PmtResult { let decompressed_bytes = Self::decompress(compression, bytes).await?; Directory::try_from(decompressed_bytes) } - async fn decompress(compression: Compression, bytes: Bytes) -> Result { + async fn decompress(compression: Compression, bytes: Bytes) -> PmtResult { let mut decompressed_bytes = Vec::with_capacity(bytes.len() * 2); match compression { Compression::Gzip => { @@ -223,7 +220,7 @@ impl AsyncPmTilesReader { /// Creates a new `PMTiles` reader from a URL using the Reqwest backend. /// /// Fails if [url] does not exist or is an invalid archive. (Note: HTTP requests are made to validate it.) - pub async fn new_with_url(client: Client, url: U) -> Result { + pub async fn new_with_url(client: Client, url: U) -> PmtResult { Self::new_with_cached_url(NoCache, client, url).await } } @@ -237,7 +234,7 @@ impl AsyncPmTilesReader { cache: C, client: Client, url: U, - ) -> Result { + ) -> PmtResult { let backend = HttpBackend::try_from(client, url)?; Self::try_from_cached_source(backend, cache).await @@ -249,7 +246,7 @@ impl AsyncPmTilesReader { /// Creates a new `PMTiles` reader from a file path using the async mmap backend. /// /// Fails if [p] does not exist or is an invalid archive. - pub async fn new_with_path>(path: P) -> Result { + pub async fn new_with_path>(path: P) -> PmtResult { Self::new_with_cached_path(NoCache, path).await } } @@ -259,7 +256,7 @@ impl AsyncPmTilesReader { /// Creates a new cached `PMTiles` reader from a file path using the async mmap backend. /// /// Fails if [p] does not exist or is an invalid archive. - pub async fn new_with_cached_path>(cache: C, path: P) -> Result { + pub async fn new_with_cached_path>(cache: C, path: P) -> PmtResult { let backend = MmapBackend::try_from(path).await?; Self::try_from_cached_source(backend, cache).await @@ -269,10 +266,10 @@ impl AsyncPmTilesReader { #[async_trait] pub trait AsyncBackend { /// Reads exactly `length` bytes starting at `offset` - async fn read_exact(&self, offset: usize, length: usize) -> Result; + async fn read_exact(&self, offset: usize, length: usize) -> PmtResult; /// Reads up to `length` bytes starting at `offset`. - async fn read(&self, offset: usize, length: usize) -> Result; + async fn read(&self, offset: usize, length: usize) -> PmtResult; } #[cfg(test)] diff --git a/src/directory.rs b/src/directory.rs index b985ec3..1a5ff58 100644 --- a/src/directory.rs +++ b/src/directory.rs @@ -42,7 +42,7 @@ impl Directory { impl TryFrom for Directory { type Error = PmtError; - fn try_from(buffer: Bytes) -> Result { + fn try_from(buffer: Bytes) -> Result { let mut buffer = buffer.reader(); let n_entries = buffer.read_usize_varint()?; diff --git a/src/error.rs b/src/error.rs index ec718d2..f6ef194 100644 --- a/src/error.rs +++ b/src/error.rs @@ -2,6 +2,10 @@ use std::string::FromUtf8Error; use thiserror::Error; +/// A specialized [`Result`] type for `PMTiles` operations. +pub type PmtResult = Result; + +/// Errors that can occur while reading `PMTiles` files. #[derive(Debug, Error)] pub enum PmtError { #[error("Invalid magic number")] diff --git a/src/header.rs b/src/header.rs index 9db9df8..3e7416f 100644 --- a/src/header.rs +++ b/src/header.rs @@ -3,7 +3,7 @@ use std::panic::catch_unwind; use bytes::{Buf, Bytes}; -use crate::error::PmtError; +use crate::error::{PmtError, PmtResult}; #[cfg(any(feature = "http-async", feature = "mmap-async-tokio"))] pub(crate) const MAX_INITIAL_BYTES: usize = 16_384; @@ -154,7 +154,7 @@ impl Header { buf.get_i32_le() as f32 / 10_000_000. } - pub fn try_from_bytes(mut bytes: Bytes) -> Result { + pub fn try_from_bytes(mut bytes: Bytes) -> PmtResult { let magic_bytes = bytes.split_to(V3_MAGIC.len()); // Assert magic diff --git a/src/http.rs b/src/http.rs index 8484890..ab7a952 100644 --- a/src/http.rs +++ b/src/http.rs @@ -4,7 +4,7 @@ use reqwest::header::{HeaderValue, RANGE}; use reqwest::{Client, IntoUrl, Method, Request, StatusCode, Url}; use crate::async_reader::AsyncBackend; -use crate::error::{PmtError, PmtHttpError}; +use crate::error::{PmtHttpError, PmtResult}; pub struct HttpBackend { client: Client, @@ -12,7 +12,7 @@ pub struct HttpBackend { } impl HttpBackend { - pub fn try_from(client: Client, url: U) -> Result { + pub fn try_from(client: Client, url: U) -> PmtResult { Ok(HttpBackend { client, pmtiles_url: url.into_url()?, @@ -22,7 +22,7 @@ impl HttpBackend { #[async_trait] impl AsyncBackend for HttpBackend { - async fn read_exact(&self, offset: usize, length: usize) -> Result { + async fn read_exact(&self, offset: usize, length: usize) -> PmtResult { let data = self.read(offset, length).await?; if data.len() == length { @@ -32,7 +32,7 @@ impl AsyncBackend for HttpBackend { } } - async fn read(&self, offset: usize, length: usize) -> Result { + async fn read(&self, offset: usize, length: usize) -> PmtResult { let end = offset + length - 1; let range = format!("bytes={offset}-{end}"); let range = HeaderValue::try_from(range).map_err(PmtHttpError::from)?; diff --git a/src/lib.rs b/src/lib.rs index 82909b9..6d7a10d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,9 +9,9 @@ mod directory; pub use directory::{DirEntry, Directory}; mod error; -pub use error::PmtError; #[cfg(feature = "http-async")] pub use error::PmtHttpError; +pub use error::{PmtError, PmtResult}; #[cfg(feature = "http-async")] pub mod http; diff --git a/src/mmap.rs b/src/mmap.rs index a82cdce..deb6230 100644 --- a/src/mmap.rs +++ b/src/mmap.rs @@ -6,14 +6,14 @@ use bytes::{Buf, Bytes}; use fmmap::tokio::{AsyncMmapFile, AsyncMmapFileExt as _, AsyncOptions}; use crate::async_reader::AsyncBackend; -use crate::error::PmtError; +use crate::error::{PmtError, PmtResult}; pub struct MmapBackend { file: AsyncMmapFile, } impl MmapBackend { - pub async fn try_from>(p: P) -> Result { + pub async fn try_from>(p: P) -> PmtResult { Ok(Self { file: AsyncMmapFile::open_with_options(p, AsyncOptions::new().read(true)) .await @@ -30,7 +30,7 @@ impl From for PmtError { #[async_trait] impl AsyncBackend for MmapBackend { - async fn read_exact(&self, offset: usize, length: usize) -> Result { + async fn read_exact(&self, offset: usize, length: usize) -> PmtResult { if self.file.len() >= offset + length { Ok(self.file.reader(offset)?.copy_to_bytes(length)) } else { @@ -40,7 +40,7 @@ impl AsyncBackend for MmapBackend { } } - async fn read(&self, offset: usize, length: usize) -> Result { + async fn read(&self, offset: usize, length: usize) -> PmtResult { let reader = self.file.reader(offset)?; let read_length = length.min(reader.len());