some more docs
This commit is contained in:
parent
1314320260
commit
41206abac1
29 changed files with 119 additions and 0 deletions
|
@ -283,6 +283,7 @@ impl Calibre {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Tests for the calibre module.
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//! Data types and functions for interacting with the calibre database.
|
||||
pub mod author;
|
||||
pub mod book;
|
||||
pub mod error;
|
||||
|
|
|
@ -24,17 +24,23 @@ pub struct MultipleAuthorsError {
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a book's author.
|
||||
pub enum BookAuthorError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareBookAuthor { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteBookAuthor { source: rusqlite::Error },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a single author.
|
||||
pub enum ScalarAuthorError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareScalarAuthor { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteScalarAuthor { source: rusqlite::Error },
|
||||
}
|
||||
|
@ -52,6 +58,7 @@ pub struct MoreAuthorsError {
|
|||
}
|
||||
|
||||
impl Author {
|
||||
/// Create an author from a database row.
|
||||
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
|
||||
Ok(Self {
|
||||
id: row.get(0)?,
|
||||
|
|
|
@ -39,25 +39,34 @@ pub struct AuthorBooksError {
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a series' books.
|
||||
pub enum SeriesBookError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareSeriesBook { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteSeriesBook { source: rusqlite::Error },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching recent books.
|
||||
pub enum RecentBooksError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareRecentBooks { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteRecentBooks { source: rusqlite::Error },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a single book.
|
||||
pub enum ScalarBookError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareScalarBook { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteScalarBook { source: rusqlite::Error },
|
||||
}
|
||||
|
@ -75,6 +84,7 @@ pub struct MoreBooksError {
|
|||
}
|
||||
|
||||
impl Book {
|
||||
/// Create a book from a database row.
|
||||
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
|
||||
Ok(Self {
|
||||
id: row.get(0)?,
|
||||
|
|
|
@ -24,17 +24,23 @@ pub struct MultiplSeriesError {
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a series' books.
|
||||
pub enum SeriesBooksError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareSeriesBooks { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteSeriesBooks { source: rusqlite::Error },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a single series.
|
||||
pub enum ScalarSeriesError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareScalarSeries { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteScalarSeries { source: rusqlite::Error },
|
||||
}
|
||||
|
@ -52,6 +58,7 @@ pub struct MoreSeriesError {
|
|||
}
|
||||
|
||||
impl Series {
|
||||
/// Create a series from a database row.
|
||||
fn from_row(row: &Row<'_>) -> Result<Self, rusqlite::Error> {
|
||||
Ok(Self {
|
||||
id: row.get(0)?,
|
||||
|
|
|
@ -35,39 +35,54 @@ const SEARCH_INIT_QUERY: &str = "INSERT INTO search.fts(book_id, data)
|
|||
GROUP BY b.id";
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when ensuring the search database is available.
|
||||
pub enum EnsureSearchDbError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareEnsureSearch { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteEnsureSearch { source: rusqlite::Error },
|
||||
/// A failure to attach the database.
|
||||
#[snafu(display("Failed to attach database."))]
|
||||
Attach { source: AttachError },
|
||||
/// A failure to initialize the database.
|
||||
#[snafu(display("Failed to initialize database."))]
|
||||
Init { source: InitError },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when attaching the search database.
|
||||
pub enum AttachError {
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteAttach { source: rusqlite::Error },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when initializing the search database.
|
||||
pub enum InitError {
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareInit { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteInit { source: rusqlite::Error },
|
||||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when searching.
|
||||
pub enum SearchError {
|
||||
/// A failure to ensure the search database is initialized.
|
||||
#[snafu(display("Failed ensure the search db is initialized."))]
|
||||
EnsureDb { source: EnsureSearchDbError },
|
||||
/// A failure to get a connection from the pool.
|
||||
#[snafu(display("Failed to get connection from pool."))]
|
||||
Connection { source: r2d2::Error },
|
||||
/// A failure to prepare the SQL statement.
|
||||
#[snafu(display("Failed to prepare statement."))]
|
||||
PrepareSearch { source: rusqlite::Error },
|
||||
/// A failure to execute the SQL statement.
|
||||
#[snafu(display("Failed to execute statement."))]
|
||||
ExecuteSearch { source: rusqlite::Error },
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use std::{
|
|||
use ignore::Walk;
|
||||
use zip::{CompressionMethod, write::SimpleFileOptions};
|
||||
|
||||
/// Create a zip archive of the source code.
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let out_dir = env::var("OUT_DIR")?;
|
||||
let src_dir = "..";
|
||||
|
|
|
@ -30,6 +30,7 @@ pub enum 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 {
|
||||
match val {
|
||||
SortOrder::ASC => calibre_db::data::pagination::SortOrder::ASC,
|
||||
|
|
|
@ -10,13 +10,17 @@ use super::SortOrder;
|
|||
use crate::data::book::Book;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving a single author.
|
||||
pub enum SingleAuthorError {
|
||||
/// A failure to fetch author data.
|
||||
#[snafu(display("Failed to fetch author data."))]
|
||||
AuthorData { source: DataStoreError },
|
||||
/// A failure to fetch books from the author.
|
||||
#[snafu(display("Failed to fetch books from author."))]
|
||||
BookData { source: DataStoreError },
|
||||
}
|
||||
|
||||
/// Retrieve a single author and all their books.
|
||||
pub async fn single(
|
||||
id: u64,
|
||||
calibre: &Calibre,
|
||||
|
|
|
@ -6,11 +6,14 @@ use snafu::{ResultExt, Snafu};
|
|||
use crate::data::book::Book;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching recent books.
|
||||
pub enum RecentBooksError {
|
||||
/// A failure to fetch recent books.
|
||||
#[snafu(display("Failed to fetch recent books."))]
|
||||
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> {
|
||||
let recent_books = calibre.recent_books(25).context(RecentBooksSnafu)?;
|
||||
let recent_books = recent_books
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//! Handlers for HTML responses.
|
||||
pub mod archive;
|
||||
pub mod authors;
|
||||
pub mod books;
|
||||
|
|
|
@ -14,7 +14,9 @@ use crate::{
|
|||
const SOURCE_ARCHIVE: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/archive.zip"));
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when downloading the source code archive.
|
||||
pub enum ArchiveError {
|
||||
/// A failure to stream the source code archive.
|
||||
#[snafu(display("Failed to stream source code archive."))]
|
||||
Download { source: DownloadError },
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving authors.
|
||||
pub enum RetrieveError {
|
||||
/// A failure to fetch pagination data.
|
||||
#[snafu(display("Failed to fetch pagination data."))]
|
||||
Authors { source: AuthorError },
|
||||
}
|
||||
|
@ -68,11 +70,14 @@ pub async fn handler(
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching an author.
|
||||
pub enum AuthorError {
|
||||
/// A failure to fetch pagination data.
|
||||
#[snafu(display("Failed to fetch pagination data."))]
|
||||
Pagination { source: PaginationError },
|
||||
}
|
||||
|
||||
/// Render a paginated list of authors.
|
||||
async fn authors(
|
||||
state: &Arc<AppState>,
|
||||
cursor: Option<&str>,
|
||||
|
@ -89,9 +94,12 @@ async fn authors(
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving a single author.
|
||||
pub enum SingleError {
|
||||
/// A failure to fetch author data.
|
||||
#[snafu(display("Failed to fetch author data."))]
|
||||
Data { source: SingleAuthorError },
|
||||
/// A failure to render the template.
|
||||
#[snafu(display("Failed to render template."))]
|
||||
Render { source: tera::Error },
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ impl HttpStatus for SearchError {
|
|||
http_error!(SearchError);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
/// Parameters for a search request.
|
||||
pub struct Params {
|
||||
/// Query for a search request.
|
||||
query: String,
|
||||
|
|
|
@ -21,7 +21,9 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving series.
|
||||
pub enum RetrieveError {
|
||||
/// A failure to fetch series data.
|
||||
#[snafu(display("Failed to fetch series data."))]
|
||||
Series { source: SeriesError },
|
||||
}
|
||||
|
@ -68,11 +70,14 @@ pub async fn handler(
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when fetching a series.
|
||||
pub enum SeriesError {
|
||||
/// A failure to fetch pagination data.
|
||||
#[snafu(display("Failed to fetch pagination data."))]
|
||||
Pagination { source: PaginationError },
|
||||
}
|
||||
|
||||
/// Render a paginated list of series.
|
||||
async fn series(
|
||||
state: &Arc<AppState>,
|
||||
cursor: Option<&str>,
|
||||
|
@ -89,9 +94,12 @@ async fn series(
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving a single series.
|
||||
pub enum SingleError {
|
||||
/// A failure to fetch series data.
|
||||
#[snafu(display("Failed to fetch series data."))]
|
||||
Data { source: SingleSeriesError },
|
||||
/// A failure to render the template.
|
||||
#[snafu(display("Failed to render template."))]
|
||||
Render { source: tera::Error },
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//! Handlers for OPDS feeds.
|
||||
pub mod authors;
|
||||
pub mod books;
|
||||
pub mod recent;
|
||||
|
|
|
@ -25,9 +25,12 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving all authors.
|
||||
pub enum AuthorsError {
|
||||
/// A failure to fetch author data.
|
||||
#[snafu(display("Failed to fetch author data."))]
|
||||
Data { source: DataStoreError },
|
||||
/// A failure to render author data.
|
||||
#[snafu(display("Failed to render author data."))]
|
||||
Render { source: AsXmlError },
|
||||
}
|
||||
|
@ -81,9 +84,12 @@ pub async fn handler(State(state): State<Arc<AppState>>) -> Result<Response, Aut
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving a single author.
|
||||
pub enum SingleError {
|
||||
/// A failure to fetch author data.
|
||||
#[snafu(display("Failed to fetch author data."))]
|
||||
AuthorData { source: SingleAuthorError },
|
||||
/// A failure to render the feed.
|
||||
#[snafu(display("Failed to render feed."))]
|
||||
FeedRender { source: AsXmlError },
|
||||
}
|
||||
|
|
|
@ -25,9 +25,12 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving books for OPDS.
|
||||
pub enum OdpsBooksError {
|
||||
/// A failure to fetch book data.
|
||||
#[snafu(display("Failed to fetch book data."))]
|
||||
Data { source: DataStoreError },
|
||||
/// A failure to render book data.
|
||||
#[snafu(display("Failed to render book data."))]
|
||||
Render { source: RenderError },
|
||||
}
|
||||
|
@ -65,7 +68,9 @@ pub async fn handler(State(state): State<Arc<AppState>>) -> Result<Response, Odp
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when rendering a feed.
|
||||
pub enum RenderError {
|
||||
/// A failure to create the OPDS feed.
|
||||
#[snafu(display("Failed to create opds feed."))]
|
||||
Feed { source: AsXmlError },
|
||||
}
|
||||
|
|
|
@ -24,9 +24,12 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving recent books.
|
||||
pub enum RecentError {
|
||||
/// A failure to fetch recent books.
|
||||
#[snafu(display("Failed to fetch recent books."))]
|
||||
Data { source: RecentBooksError },
|
||||
/// A failure to render the feed.
|
||||
#[snafu(display("Failed to render feed."))]
|
||||
Render { source: AsXmlError },
|
||||
}
|
||||
|
|
|
@ -25,9 +25,12 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when searching for books.
|
||||
pub enum SearchError {
|
||||
/// A failure to query for books.
|
||||
#[snafu(display("Failed to query books."))]
|
||||
Query { source: SearchQueryError },
|
||||
/// A failure to render the feed.
|
||||
#[snafu(display("Failed to render feed."))]
|
||||
Render { source: RenderError },
|
||||
}
|
||||
|
@ -42,6 +45,7 @@ impl HttpStatus for SearchError {
|
|||
http_error!(SearchError);
|
||||
|
||||
#[derive(Deserialize)]
|
||||
/// Parameters for a search request.
|
||||
pub struct Params {
|
||||
/// Query for a search request.
|
||||
query: String,
|
||||
|
@ -67,7 +71,9 @@ pub async fn handler(
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving search information.
|
||||
pub enum InfoError {
|
||||
/// A failure to render the feed.
|
||||
#[snafu(display("Failed to render feed."))]
|
||||
FeedRender { source: AsXmlError },
|
||||
}
|
||||
|
@ -81,6 +87,7 @@ impl HttpStatus for InfoError {
|
|||
|
||||
http_error!(InfoError);
|
||||
|
||||
/// Render search information as an OPDS feed.
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/search/info",
|
||||
|
|
|
@ -25,9 +25,12 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving all series.
|
||||
pub enum SeriesError {
|
||||
/// A failure to fetch series data.
|
||||
#[snafu(display("Failed to fetch series data."))]
|
||||
Data { source: DataStoreError },
|
||||
/// A failure to render series data.
|
||||
#[snafu(display("Failed to render series data."))]
|
||||
Render { source: AsXmlError },
|
||||
}
|
||||
|
@ -81,9 +84,12 @@ pub async fn handler(State(state): State<Arc<AppState>>) -> Result<Response, Ser
|
|||
}
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving a single series.
|
||||
pub enum SingleError {
|
||||
/// A failure to fetch series data.
|
||||
#[snafu(display("Failed to fetch series data."))]
|
||||
SeriesData { source: SingleSeriesError },
|
||||
/// A failure to render the feed.
|
||||
#[snafu(display("Failed to render feed."))]
|
||||
FeedRender { source: AsXmlError },
|
||||
}
|
||||
|
|
|
@ -11,13 +11,18 @@ use tera::Context;
|
|||
use crate::templates::TEMPLATES;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur during pagination.
|
||||
pub enum PaginationError {
|
||||
/// A failure to fetch pagination data.
|
||||
#[snafu(display("Failed to fetch pagination data."))]
|
||||
Fetch { source: DataStoreError },
|
||||
/// A failure to render the template.
|
||||
#[snafu(display("Failed to render template."))]
|
||||
Template { source: tera::Error },
|
||||
/// A failure to fetch previous items.
|
||||
#[snafu(display("Failed to fetch previous items."))]
|
||||
Previous { source: DataStoreError },
|
||||
/// A failure to fetch more items.
|
||||
#[snafu(display("Failed to fetch more items."))]
|
||||
More { source: DataStoreError },
|
||||
}
|
||||
|
|
0
little-hesinde/src/api/recent.rs
Normal file
0
little-hesinde/src/api/recent.rs
Normal file
|
@ -6,11 +6,14 @@ use snafu::{ResultExt, Snafu};
|
|||
use crate::data::book::Book;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when querying for books.
|
||||
pub enum SearchQueryError {
|
||||
/// A failure to query the database.
|
||||
#[snafu(display("Failed to search for books."))]
|
||||
Db { source: DataStoreError },
|
||||
}
|
||||
|
||||
/// Query for books and enrich them with additional information.
|
||||
pub async fn query(
|
||||
query: &str,
|
||||
calibre: &Calibre,
|
||||
|
|
|
@ -9,13 +9,17 @@ use snafu::{ResultExt, Snafu};
|
|||
use crate::data::book::Book;
|
||||
|
||||
#[derive(Debug, Snafu)]
|
||||
/// Errors that can occur when retrieving a single series.
|
||||
pub enum SingleSeriesError {
|
||||
/// A failure to fetch series data.
|
||||
#[snafu(display("Failed to fetch series data."))]
|
||||
SeriesData { source: DataStoreError },
|
||||
/// A failure to fetch books in the series.
|
||||
#[snafu(display("Failed to fetch books in series."))]
|
||||
BookData { source: DataStoreError },
|
||||
}
|
||||
|
||||
/// Retrieve a single series and all its books.
|
||||
pub async fn single(
|
||||
id: u64,
|
||||
calibre: &Calibre,
|
||||
|
|
|
@ -28,6 +28,7 @@ pub async fn handler(uri: Uri) -> impl IntoResponse {
|
|||
StaticFile(path)
|
||||
}
|
||||
|
||||
/// A wrapper type for static files.
|
||||
pub struct StaticFile<T>(pub T);
|
||||
|
||||
impl<T> IntoResponse for StaticFile<T>
|
||||
|
|
|
@ -14,17 +14,22 @@ use crate::cli::Cli;
|
|||
/// Errors from loading application configuration.
|
||||
#[derive(Debug, Snafu)]
|
||||
pub enum LoadError {
|
||||
/// The provided path is not a calibre library.
|
||||
#[snafu(display("{path} is not a calibre library."))]
|
||||
LibraryPath { path: String },
|
||||
/// Could not find the calibre metadata database.
|
||||
#[snafu(display("Could not find calibre metadata at {path}."))]
|
||||
MetadataPath { path: String },
|
||||
/// The listening address could not be parsed.
|
||||
#[snafu(display("Invalid listening address {listen_address}."))]
|
||||
ListeningAddressParse {
|
||||
source: io::Error,
|
||||
listen_address: String,
|
||||
},
|
||||
/// The listening address is invalid.
|
||||
#[snafu(display("Invalid listening address {listen_address}."))]
|
||||
ListeningAddress { listen_address: String },
|
||||
/// The cache directory could not be created.
|
||||
#[snafu(display("Failed to create cach directory at {path}."))]
|
||||
CacheDir { source: io::Error, path: String },
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
//! Data types and functions for enriching calibre data.
|
||||
pub mod book;
|
||||
|
|
|
@ -17,8 +17,10 @@ use super::error::{
|
|||
/// Url pointing to a location.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Url {
|
||||
/// The media type of the resource.
|
||||
#[serde(rename = "@type")]
|
||||
pub type_name: String,
|
||||
/// The URL template.
|
||||
#[serde(rename = "@template")]
|
||||
pub template: String,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue