open-library-api-rs 0.1.0

Async Rust client for the Open Library API
Documentation
// v0.0.1
use serde::{Deserialize, Serialize};

/// A reference to an Open Library resource, e.g. `{ "key": "/works/OL45804W" }`.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Key {
    pub key: String,
}

/// A typed reference that also carries the object type name.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct TypedKey {
    pub key: String,
    #[serde(rename = "type")]
    pub kind: String,
}

/// A hyperlink with a URL and optional title.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Link {
    pub url: String,
    #[serde(default)]
    pub title: Option<String>,
}

/// A value that Open Library sometimes returns as a plain string and sometimes as
/// `{ "value": "..." }`. Use `TextOrValue::into_text()` to normalise.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum TextOrValue {
    Text(String),
    Value { value: String },
}

impl TextOrValue {
    pub fn into_text(self) -> String {
        match self {
            TextOrValue::Text(s) => s,
            TextOrValue::Value { value } => value,
        }
    }

    pub fn as_str(&self) -> &str {
        match self {
            TextOrValue::Text(s) => s.as_str(),
            TextOrValue::Value { value } => value.as_str(),
        }
    }
}

/// An integer that Open Library sometimes wraps as `{ "value": 123 }`.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum IntOrValue {
    Int(i64),
    Value { value: i64 },
}

impl IntOrValue {
    pub fn value(&self) -> i64 {
        match self {
            IntOrValue::Int(n) => *n,
            IntOrValue::Value { value } => *value,
        }
    }
}

/// Pagination links returned in some list-style responses.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PaginationLinks {
    #[serde(rename = "self")]
    pub self_url: Option<String>,
    pub next: Option<String>,
    pub prev: Option<String>,
}

/// Cover / photo image sizes.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ImageSize {
    #[serde(rename = "S")]
    Small,
    #[serde(rename = "M")]
    Medium,
    #[serde(rename = "L")]
    Large,
}

impl ImageSize {
    pub fn as_str(self) -> &'static str {
        match self {
            ImageSize::Small => "S",
            ImageSize::Medium => "M",
            ImageSize::Large => "L",
        }
    }
}

/// The key type used when querying covers.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CoverKey {
    /// Internal numeric cover ID.
    Id,
    Isbn,
    Oclc,
    Lccn,
    Olid,
}

impl CoverKey {
    pub fn as_str(self) -> &'static str {
        match self {
            CoverKey::Id => "id",
            CoverKey::Isbn => "isbn",
            CoverKey::Oclc => "oclc",
            CoverKey::Lccn => "lccn",
            CoverKey::Olid => "olid",
        }
    }
}

/// Identifier type used by the Partner (Volumes) API.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VolumeIdType {
    Isbn,
    Lccn,
    Oclc,
    Olid,
}

impl VolumeIdType {
    pub fn as_str(self) -> &'static str {
        match self {
            VolumeIdType::Isbn => "isbn",
            VolumeIdType::Lccn => "lccn",
            VolumeIdType::Oclc => "oclc",
            VolumeIdType::Olid => "olid",
        }
    }
}

/// Kind of change in the Recent Changes API.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ChangeKind {
    AddCover,
    AddBook,
    EditBook,
    MergeAuthors,
    Update,
    Revert,
    NewAccount,
    Register,
    Lists,
    #[serde(other)]
    Other,
}

impl ChangeKind {
    pub fn as_str(&self) -> &str {
        match self {
            ChangeKind::AddCover => "add-cover",
            ChangeKind::AddBook => "add-book",
            ChangeKind::EditBook => "edit-book",
            ChangeKind::MergeAuthors => "merge-authors",
            ChangeKind::Update => "update",
            ChangeKind::Revert => "revert",
            ChangeKind::NewAccount => "new-account",
            ChangeKind::Register => "register",
            ChangeKind::Lists => "lists",
            ChangeKind::Other => "other",
        }
    }
}

/// Reading shelf identifier.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReadingShelf {
    WantToRead,
    CurrentlyReading,
    AlreadyRead,
}

impl ReadingShelf {
    pub fn as_str(self) -> &'static str {
        match self {
            ReadingShelf::WantToRead => "want-to-read",
            ReadingShelf::CurrentlyReading => "currently-reading",
            ReadingShelf::AlreadyRead => "already-read",
        }
    }
}

/// Sort order for search.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SortOrder {
    Relevance,
    NewestFirst,
    OldestFirst,
}

impl SortOrder {
    pub fn as_str(self) -> &'static str {
        match self {
            SortOrder::Relevance => "relevance",
            SortOrder::NewestFirst => "new",
            SortOrder::OldestFirst => "old",
        }
    }
}

/// `jscmd` parameter for the `/api/books` endpoint.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BooksJsCmd {
    Data,
    Details,
    ViewApi,
}

impl BooksJsCmd {
    pub fn as_str(self) -> &'static str {
        match self {
            BooksJsCmd::Data => "data",
            BooksJsCmd::Details => "details",
            BooksJsCmd::ViewApi => "viewapi",
        }
    }
}