some more docs

This commit is contained in:
Sebastian Hugentobler 2025-07-02 21:57:44 +02:00
parent 1314320260
commit 41206abac1
Signed by: shu
SSH key fingerprint: SHA256:ppcx6MlixdNZd5EUM1nkHOKoyQYoJwzuQKXM6J/t66M
29 changed files with 119 additions and 0 deletions

View file

@ -283,6 +283,7 @@ impl Calibre {
} }
#[cfg(test)] #[cfg(test)]
/// Tests for the calibre module.
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,3 +1,4 @@
//! Data types and functions for interacting with the calibre database.
pub mod author; pub mod author;
pub mod book; pub mod book;
pub mod error; pub mod error;

View file

@ -24,17 +24,23 @@ pub struct MultipleAuthorsError {
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a book's author.
pub enum BookAuthorError { pub enum BookAuthorError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareBookAuthor { source: rusqlite::Error }, PrepareBookAuthor { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteBookAuthor { source: rusqlite::Error }, ExecuteBookAuthor { source: rusqlite::Error },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a single author.
pub enum ScalarAuthorError { pub enum ScalarAuthorError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareScalarAuthor { source: rusqlite::Error }, PrepareScalarAuthor { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteScalarAuthor { source: rusqlite::Error }, ExecuteScalarAuthor { source: rusqlite::Error },
} }
@ -52,6 +58,7 @@ pub struct MoreAuthorsError {
} }
impl Author { impl Author {
/// Create an author from a database row.
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> { fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self { Ok(Self {
id: row.get(0)?, id: row.get(0)?,

View file

@ -39,25 +39,34 @@ pub struct AuthorBooksError {
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a series' books.
pub enum SeriesBookError { pub enum SeriesBookError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareSeriesBook { source: rusqlite::Error }, PrepareSeriesBook { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteSeriesBook { source: rusqlite::Error }, ExecuteSeriesBook { source: rusqlite::Error },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching recent books.
pub enum RecentBooksError { pub enum RecentBooksError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareRecentBooks { source: rusqlite::Error }, PrepareRecentBooks { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteRecentBooks { source: rusqlite::Error }, ExecuteRecentBooks { source: rusqlite::Error },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a single book.
pub enum ScalarBookError { pub enum ScalarBookError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareScalarBook { source: rusqlite::Error }, PrepareScalarBook { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteScalarBook { source: rusqlite::Error }, ExecuteScalarBook { source: rusqlite::Error },
} }
@ -75,6 +84,7 @@ pub struct MoreBooksError {
} }
impl Book { impl Book {
/// Create a book from a database row.
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> { fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self { Ok(Self {
id: row.get(0)?, id: row.get(0)?,

View file

@ -24,17 +24,23 @@ pub struct MultiplSeriesError {
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a series' books.
pub enum SeriesBooksError { pub enum SeriesBooksError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareSeriesBooks { source: rusqlite::Error }, PrepareSeriesBooks { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteSeriesBooks { source: rusqlite::Error }, ExecuteSeriesBooks { source: rusqlite::Error },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a single series.
pub enum ScalarSeriesError { pub enum ScalarSeriesError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareScalarSeries { source: rusqlite::Error }, PrepareScalarSeries { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteScalarSeries { source: rusqlite::Error }, ExecuteScalarSeries { source: rusqlite::Error },
} }
@ -52,6 +58,7 @@ pub struct MoreSeriesError {
} }
impl Series { impl Series {
/// Create a series from a database row.
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> { fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
Ok(Self { Ok(Self {
id: row.get(0)?, id: row.get(0)?,

View file

@ -35,39 +35,54 @@ const SEARCH_INIT_QUERY: &str = "INSERT INTO search.fts(book_id, data)
GROUP BY b.id"; GROUP BY b.id";
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when ensuring the search database is available.
pub enum EnsureSearchDbError { pub enum EnsureSearchDbError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareEnsureSearch { source: rusqlite::Error }, PrepareEnsureSearch { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteEnsureSearch { source: rusqlite::Error }, ExecuteEnsureSearch { source: rusqlite::Error },
/// A failure to attach the database.
#[snafu(display("Failed to attach database."))] #[snafu(display("Failed to attach database."))]
Attach { source: AttachError }, Attach { source: AttachError },
/// A failure to initialize the database.
#[snafu(display("Failed to initialize database."))] #[snafu(display("Failed to initialize database."))]
Init { source: InitError }, Init { source: InitError },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when attaching the search database.
pub enum AttachError { pub enum AttachError {
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteAttach { source: rusqlite::Error }, ExecuteAttach { source: rusqlite::Error },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when initializing the search database.
pub enum InitError { pub enum InitError {
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareInit { source: rusqlite::Error }, PrepareInit { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteInit { source: rusqlite::Error }, ExecuteInit { source: rusqlite::Error },
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when searching.
pub enum SearchError { pub enum SearchError {
/// A failure to ensure the search database is initialized.
#[snafu(display("Failed ensure the search db is initialized."))] #[snafu(display("Failed ensure the search db is initialized."))]
EnsureDb { source: EnsureSearchDbError }, EnsureDb { source: EnsureSearchDbError },
/// A failure to get a connection from the pool.
#[snafu(display("Failed to get connection from pool."))] #[snafu(display("Failed to get connection from pool."))]
Connection { source: r2d2::Error }, Connection { source: r2d2::Error },
/// A failure to prepare the SQL statement.
#[snafu(display("Failed to prepare statement."))] #[snafu(display("Failed to prepare statement."))]
PrepareSearch { source: rusqlite::Error }, PrepareSearch { source: rusqlite::Error },
/// A failure to execute the SQL statement.
#[snafu(display("Failed to execute statement."))] #[snafu(display("Failed to execute statement."))]
ExecuteSearch { source: rusqlite::Error }, ExecuteSearch { source: rusqlite::Error },
} }

View file

@ -8,6 +8,7 @@ use std::{
use ignore::Walk; use ignore::Walk;
use zip::{CompressionMethod, write::SimpleFileOptions}; use zip::{CompressionMethod, write::SimpleFileOptions};
/// Create a zip archive of the source code.
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_dir = env::var("OUT_DIR")?; let out_dir = env::var("OUT_DIR")?;
let src_dir = ".."; let src_dir = "..";

View file

@ -30,6 +30,7 @@ pub enum SortOrder {
} }
impl From<SortOrder> for calibre_db::data::pagination::SortOrder { impl From<SortOrder> for calibre_db::data::pagination::SortOrder {
/// Convert the API sort order to the database sort order.
fn from(val: SortOrder) -> Self { fn from(val: SortOrder) -> Self {
match val { match val {
SortOrder::ASC => calibre_db::data::pagination::SortOrder::ASC, SortOrder::ASC => calibre_db::data::pagination::SortOrder::ASC,

View file

@ -10,13 +10,17 @@ use super::SortOrder;
use crate::data::book::Book; use crate::data::book::Book;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving a single author.
pub enum SingleAuthorError { pub enum SingleAuthorError {
/// A failure to fetch author data.
#[snafu(display("Failed to fetch author data."))] #[snafu(display("Failed to fetch author data."))]
AuthorData { source: DataStoreError }, AuthorData { source: DataStoreError },
/// A failure to fetch books from the author.
#[snafu(display("Failed to fetch books from author."))] #[snafu(display("Failed to fetch books from author."))]
BookData { source: DataStoreError }, BookData { source: DataStoreError },
} }
/// Retrieve a single author and all their books.
pub async fn single( pub async fn single(
id: u64, id: u64,
calibre: &Calibre, calibre: &Calibre,

View file

@ -6,11 +6,14 @@ use snafu::{ResultExt, Snafu};
use crate::data::book::Book; use crate::data::book::Book;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching recent books.
pub enum RecentBooksError { pub enum RecentBooksError {
/// A failure to fetch recent books.
#[snafu(display("Failed to fetch recent books."))] #[snafu(display("Failed to fetch recent books."))]
RecentBooks { source: DataStoreError }, RecentBooks { source: DataStoreError },
} }
/// Fetch recent books and enrich them with additional information.
pub async fn recent(calibre: &Calibre, library_path: &Path) -> Result<Vec<Book>, RecentBooksError> { pub async fn recent(calibre: &Calibre, library_path: &Path) -> Result<Vec<Book>, RecentBooksError> {
let recent_books = calibre.recent_books(25).context(RecentBooksSnafu)?; let recent_books = calibre.recent_books(25).context(RecentBooksSnafu)?;
let recent_books = recent_books let recent_books = recent_books

View file

@ -1,3 +1,4 @@
//! Handlers for HTML responses.
pub mod archive; pub mod archive;
pub mod authors; pub mod authors;
pub mod books; pub mod books;

View file

@ -14,7 +14,9 @@ use crate::{
const SOURCE_ARCHIVE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/archive.zip")); const SOURCE_ARCHIVE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/archive.zip"));
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when downloading the source code archive.
pub enum ArchiveError { pub enum ArchiveError {
/// A failure to stream the source code archive.
#[snafu(display("Failed to stream source code archive."))] #[snafu(display("Failed to stream source code archive."))]
Download { source: DownloadError }, Download { source: DownloadError },
} }

View file

@ -21,7 +21,9 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving authors.
pub enum RetrieveError { pub enum RetrieveError {
/// A failure to fetch pagination data.
#[snafu(display("Failed to fetch pagination data."))] #[snafu(display("Failed to fetch pagination data."))]
Authors { source: AuthorError }, Authors { source: AuthorError },
} }
@ -68,11 +70,14 @@ pub async fn handler(
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching an author.
pub enum AuthorError { pub enum AuthorError {
/// A failure to fetch pagination data.
#[snafu(display("Failed to fetch pagination data."))] #[snafu(display("Failed to fetch pagination data."))]
Pagination { source: PaginationError }, Pagination { source: PaginationError },
} }
/// Render a paginated list of authors.
async fn authors( async fn authors(
state: &Arc<AppState>, state: &Arc<AppState>,
cursor: Option<&str>, cursor: Option<&str>,
@ -89,9 +94,12 @@ async fn authors(
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving a single author.
pub enum SingleError { pub enum SingleError {
/// A failure to fetch author data.
#[snafu(display("Failed to fetch author data."))] #[snafu(display("Failed to fetch author data."))]
Data { source: SingleAuthorError }, Data { source: SingleAuthorError },
/// A failure to render the template.
#[snafu(display("Failed to render template."))] #[snafu(display("Failed to render template."))]
Render { source: tera::Error }, Render { source: tera::Error },
} }

View file

@ -39,6 +39,7 @@ impl HttpStatus for SearchError {
http_error!(SearchError); http_error!(SearchError);
#[derive(Deserialize)] #[derive(Deserialize)]
/// Parameters for a search request.
pub struct Params { pub struct Params {
/// Query for a search request. /// Query for a search request.
query: String, query: String,

View file

@ -21,7 +21,9 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving series.
pub enum RetrieveError { pub enum RetrieveError {
/// A failure to fetch series data.
#[snafu(display("Failed to fetch series data."))] #[snafu(display("Failed to fetch series data."))]
Series { source: SeriesError }, Series { source: SeriesError },
} }
@ -68,11 +70,14 @@ pub async fn handler(
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when fetching a series.
pub enum SeriesError { pub enum SeriesError {
/// A failure to fetch pagination data.
#[snafu(display("Failed to fetch pagination data."))] #[snafu(display("Failed to fetch pagination data."))]
Pagination { source: PaginationError }, Pagination { source: PaginationError },
} }
/// Render a paginated list of series.
async fn series( async fn series(
state: &Arc<AppState>, state: &Arc<AppState>,
cursor: Option<&str>, cursor: Option<&str>,
@ -89,9 +94,12 @@ async fn series(
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving a single series.
pub enum SingleError { pub enum SingleError {
/// A failure to fetch series data.
#[snafu(display("Failed to fetch series data."))] #[snafu(display("Failed to fetch series data."))]
Data { source: SingleSeriesError }, Data { source: SingleSeriesError },
/// A failure to render the template.
#[snafu(display("Failed to render template."))] #[snafu(display("Failed to render template."))]
Render { source: tera::Error }, Render { source: tera::Error },
} }

View file

@ -1,3 +1,4 @@
//! Handlers for OPDS feeds.
pub mod authors; pub mod authors;
pub mod books; pub mod books;
pub mod recent; pub mod recent;

View file

@ -25,9 +25,12 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving all authors.
pub enum AuthorsError { pub enum AuthorsError {
/// A failure to fetch author data.
#[snafu(display("Failed to fetch author data."))] #[snafu(display("Failed to fetch author data."))]
Data { source: DataStoreError }, Data { source: DataStoreError },
/// A failure to render author data.
#[snafu(display("Failed to render author data."))] #[snafu(display("Failed to render author data."))]
Render { source: AsXmlError }, Render { source: AsXmlError },
} }
@ -81,9 +84,12 @@ pub async fn handler(State(state): State<Arc<AppState>>) -> Result<Response, Aut
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving a single author.
pub enum SingleError { pub enum SingleError {
/// A failure to fetch author data.
#[snafu(display("Failed to fetch author data."))] #[snafu(display("Failed to fetch author data."))]
AuthorData { source: SingleAuthorError }, AuthorData { source: SingleAuthorError },
/// A failure to render the feed.
#[snafu(display("Failed to render feed."))] #[snafu(display("Failed to render feed."))]
FeedRender { source: AsXmlError }, FeedRender { source: AsXmlError },
} }

View file

@ -25,9 +25,12 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving books for OPDS.
pub enum OdpsBooksError { pub enum OdpsBooksError {
/// A failure to fetch book data.
#[snafu(display("Failed to fetch book data."))] #[snafu(display("Failed to fetch book data."))]
Data { source: DataStoreError }, Data { source: DataStoreError },
/// A failure to render book data.
#[snafu(display("Failed to render book data."))] #[snafu(display("Failed to render book data."))]
Render { source: RenderError }, Render { source: RenderError },
} }
@ -65,7 +68,9 @@ pub async fn handler(State(state): State<Arc<AppState>>) -> Result<Response, Odp
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when rendering a feed.
pub enum RenderError { pub enum RenderError {
/// A failure to create the OPDS feed.
#[snafu(display("Failed to create opds feed."))] #[snafu(display("Failed to create opds feed."))]
Feed { source: AsXmlError }, Feed { source: AsXmlError },
} }

View file

@ -24,9 +24,12 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving recent books.
pub enum RecentError { pub enum RecentError {
/// A failure to fetch recent books.
#[snafu(display("Failed to fetch recent books."))] #[snafu(display("Failed to fetch recent books."))]
Data { source: RecentBooksError }, Data { source: RecentBooksError },
/// A failure to render the feed.
#[snafu(display("Failed to render feed."))] #[snafu(display("Failed to render feed."))]
Render { source: AsXmlError }, Render { source: AsXmlError },
} }

View file

@ -25,9 +25,12 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when searching for books.
pub enum SearchError { pub enum SearchError {
/// A failure to query for books.
#[snafu(display("Failed to query books."))] #[snafu(display("Failed to query books."))]
Query { source: SearchQueryError }, Query { source: SearchQueryError },
/// A failure to render the feed.
#[snafu(display("Failed to render feed."))] #[snafu(display("Failed to render feed."))]
Render { source: RenderError }, Render { source: RenderError },
} }
@ -42,6 +45,7 @@ impl HttpStatus for SearchError {
http_error!(SearchError); http_error!(SearchError);
#[derive(Deserialize)] #[derive(Deserialize)]
/// Parameters for a search request.
pub struct Params { pub struct Params {
/// Query for a search request. /// Query for a search request.
query: String, query: String,
@ -67,7 +71,9 @@ pub async fn handler(
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving search information.
pub enum InfoError { pub enum InfoError {
/// A failure to render the feed.
#[snafu(display("Failed to render feed."))] #[snafu(display("Failed to render feed."))]
FeedRender { source: AsXmlError }, FeedRender { source: AsXmlError },
} }
@ -81,6 +87,7 @@ impl HttpStatus for InfoError {
http_error!(InfoError); http_error!(InfoError);
/// Render search information as an OPDS feed.
#[utoipa::path( #[utoipa::path(
get, get,
path = "/search/info", path = "/search/info",

View file

@ -25,9 +25,12 @@ use crate::{
}; };
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving all series.
pub enum SeriesError { pub enum SeriesError {
/// A failure to fetch series data.
#[snafu(display("Failed to fetch series data."))] #[snafu(display("Failed to fetch series data."))]
Data { source: DataStoreError }, Data { source: DataStoreError },
/// A failure to render series data.
#[snafu(display("Failed to render series data."))] #[snafu(display("Failed to render series data."))]
Render { source: AsXmlError }, Render { source: AsXmlError },
} }
@ -81,9 +84,12 @@ pub async fn handler(State(state): State<Arc<AppState>>) -> Result<Response, Ser
} }
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving a single series.
pub enum SingleError { pub enum SingleError {
/// A failure to fetch series data.
#[snafu(display("Failed to fetch series data."))] #[snafu(display("Failed to fetch series data."))]
SeriesData { source: SingleSeriesError }, SeriesData { source: SingleSeriesError },
/// A failure to render the feed.
#[snafu(display("Failed to render feed."))] #[snafu(display("Failed to render feed."))]
FeedRender { source: AsXmlError }, FeedRender { source: AsXmlError },
} }

View file

@ -11,13 +11,18 @@ use tera::Context;
use crate::templates::TEMPLATES; use crate::templates::TEMPLATES;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur during pagination.
pub enum PaginationError { pub enum PaginationError {
/// A failure to fetch pagination data.
#[snafu(display("Failed to fetch pagination data."))] #[snafu(display("Failed to fetch pagination data."))]
Fetch { source: DataStoreError }, Fetch { source: DataStoreError },
/// A failure to render the template.
#[snafu(display("Failed to render template."))] #[snafu(display("Failed to render template."))]
Template { source: tera::Error }, Template { source: tera::Error },
/// A failure to fetch previous items.
#[snafu(display("Failed to fetch previous items."))] #[snafu(display("Failed to fetch previous items."))]
Previous { source: DataStoreError }, Previous { source: DataStoreError },
/// A failure to fetch more items.
#[snafu(display("Failed to fetch more items."))] #[snafu(display("Failed to fetch more items."))]
More { source: DataStoreError }, More { source: DataStoreError },
} }

View file

View file

@ -6,11 +6,14 @@ use snafu::{ResultExt, Snafu};
use crate::data::book::Book; use crate::data::book::Book;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when querying for books.
pub enum SearchQueryError { pub enum SearchQueryError {
/// A failure to query the database.
#[snafu(display("Failed to search for books."))] #[snafu(display("Failed to search for books."))]
Db { source: DataStoreError }, Db { source: DataStoreError },
} }
/// Query for books and enrich them with additional information.
pub async fn query( pub async fn query(
query: &str, query: &str,
calibre: &Calibre, calibre: &Calibre,

View file

@ -9,13 +9,17 @@ use snafu::{ResultExt, Snafu};
use crate::data::book::Book; use crate::data::book::Book;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
/// Errors that can occur when retrieving a single series.
pub enum SingleSeriesError { pub enum SingleSeriesError {
/// A failure to fetch series data.
#[snafu(display("Failed to fetch series data."))] #[snafu(display("Failed to fetch series data."))]
SeriesData { source: DataStoreError }, SeriesData { source: DataStoreError },
/// A failure to fetch books in the series.
#[snafu(display("Failed to fetch books in series."))] #[snafu(display("Failed to fetch books in series."))]
BookData { source: DataStoreError }, BookData { source: DataStoreError },
} }
/// Retrieve a single series and all its books.
pub async fn single( pub async fn single(
id: u64, id: u64,
calibre: &Calibre, calibre: &Calibre,

View file

@ -28,6 +28,7 @@ pub async fn handler(uri: Uri) -> impl IntoResponse {
StaticFile(path) StaticFile(path)
} }
/// A wrapper type for static files.
pub struct StaticFile<T>(pub T); pub struct StaticFile<T>(pub T);
impl<T> IntoResponse for StaticFile<T> impl<T> IntoResponse for StaticFile<T>

View file

@ -14,17 +14,22 @@ use crate::cli::Cli;
/// Errors from loading application configuration. /// Errors from loading application configuration.
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
pub enum LoadError { pub enum LoadError {
/// The provided path is not a calibre library.
#[snafu(display("{path} is not a calibre library."))] #[snafu(display("{path} is not a calibre library."))]
LibraryPath { path: String }, LibraryPath { path: String },
/// Could not find the calibre metadata database.
#[snafu(display("Could not find calibre metadata at {path}."))] #[snafu(display("Could not find calibre metadata at {path}."))]
MetadataPath { path: String }, MetadataPath { path: String },
/// The listening address could not be parsed.
#[snafu(display("Invalid listening address {listen_address}."))] #[snafu(display("Invalid listening address {listen_address}."))]
ListeningAddressParse { ListeningAddressParse {
source: io::Error, source: io::Error,
listen_address: String, listen_address: String,
}, },
/// The listening address is invalid.
#[snafu(display("Invalid listening address {listen_address}."))] #[snafu(display("Invalid listening address {listen_address}."))]
ListeningAddress { listen_address: String }, ListeningAddress { listen_address: String },
/// The cache directory could not be created.
#[snafu(display("Failed to create cach directory at {path}."))] #[snafu(display("Failed to create cach directory at {path}."))]
CacheDir { source: io::Error, path: String }, CacheDir { source: io::Error, path: String },
} }

View file

@ -1 +1,2 @@
//! Data types and functions for enriching calibre data.
pub mod book; pub mod book;

View file

@ -17,8 +17,10 @@ use super::error::{
/// Url pointing to a location. /// Url pointing to a location.
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct Url { pub struct Url {
/// The media type of the resource.
#[serde(rename = "@type")] #[serde(rename = "@type")]
pub type_name: String, pub type_name: String,
/// The URL template.
#[serde(rename = "@template")] #[serde(rename = "@template")]
pub template: String, pub template: String,
} }