open_library/models/
account.rs

1use crate::models::OpenLibraryResource;
2use crate::{OpenLibraryClient, OpenLibraryError, OpenLibraryErrorResponse};
3use chrono::{DateTime, Utc};
4use serde::de::Error;
5use serde::{Deserialize, Deserializer, Serialize};
6
7#[derive(Serialize)]
8pub struct LoginRequest {
9    pub username: String,
10    pub password: String,
11}
12
13pub enum ReadingLogResponseWrapper {
14    Success(ReadingLogResponse),
15    Err(OpenLibraryErrorResponse),
16}
17
18impl<'de> Deserialize<'de> for ReadingLogResponseWrapper {
19    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
20    where
21        D: Deserializer<'de>,
22    {
23        let json: serde_json::Value = Deserialize::deserialize(deserializer)?;
24
25        match json.get("error") {
26            None => Ok(ReadingLogResponseWrapper::Success(
27                serde_json::from_value(json).map_err(D::Error::custom)?,
28            )),
29            Some(_) => Ok(ReadingLogResponseWrapper::Err(
30                serde_json::from_value(json).map_err(D::Error::custom)?,
31            )),
32        }
33    }
34}
35
36#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
37pub struct Session {
38    cookie: String,
39    username: String,
40}
41
42impl Session {
43    pub fn from(cookie: String, username: String) -> Self {
44        Session { cookie, username }
45    }
46
47    pub fn cookie(&self) -> &String {
48        &self.cookie
49    }
50
51    pub fn username(&self) -> &String {
52        &self.username
53    }
54}
55
56#[derive(Clone)]
57pub enum ReadingLog {
58    AlreadyRead,
59    CurrentlyReading,
60    WantToRead,
61}
62
63impl ReadingLog {
64    pub fn url(&self) -> &str {
65        match self {
66            ReadingLog::AlreadyRead => "already-read.json",
67            ReadingLog::CurrentlyReading => "currently-reading.json",
68            ReadingLog::WantToRead => "want-to-read.json",
69        }
70    }
71
72    pub async fn retrieve_for(
73        &self,
74        client: &OpenLibraryClient,
75        username: String,
76    ) -> Result<Vec<ReadingLogEntry>, OpenLibraryError> {
77        match self {
78            ReadingLog::AlreadyRead => client.account.get_already_read(username).await,
79            ReadingLog::CurrentlyReading => client.account.get_currently_reading(username).await,
80            ReadingLog::WantToRead => client.account.get_want_to_read(username).await,
81        }
82    }
83}
84
85#[derive(Debug, Deserialize, Serialize)]
86pub struct ReadingLogResponse {
87    pub page: i16,
88    pub reading_log_entries: Vec<ReadingLogEntry>,
89}
90
91#[derive(Clone, Debug, Deserialize, Serialize)]
92pub struct ReadingLogEntry {
93    pub work: ReadingLogWork,
94    pub logged_edition: OpenLibraryResource,
95    #[serde(with = "crate::format::datetime")]
96    pub logged_date: DateTime<Utc>,
97}
98
99#[derive(Clone, Debug, Deserialize, Serialize)]
100pub struct ReadingLogWork {
101    pub title: String,
102    pub key: OpenLibraryResource,
103    pub author_keys: Vec<OpenLibraryResource>,
104    pub author_names: Vec<String>,
105    pub first_publish_year: Option<i32>,
106    pub lending_edition_s: Option<String>,
107    pub edition_key: Vec<String>,
108    pub cover_id: Option<i32>,
109    pub cover_edition_key: Option<String>,
110}