lib/models/
book.rs

1//! Defines the [`Book`] struct.
2
3use rusqlite::Row;
4use serde::Serialize;
5
6use crate::applebooks::ios::models::BookRaw;
7use crate::applebooks::macos::ABQuery;
8
9use super::datetime::DateTimeUtc;
10
11/// A struct represening a book and its metadata.
12#[derive(Debug, Default, Clone, Serialize)]
13pub struct Book {
14    /// The title of the book.
15    pub title: String,
16
17    /// The author of the book.
18    pub author: String,
19
20    /// The book's metadata.
21    pub metadata: BookMetadata,
22}
23
24// For macOS.
25impl ABQuery for Book {
26    const QUERY: &'static str = {
27        "SELECT
28            ZBKLIBRARYASSET.ZTITLE,        -- 0 title
29            ZBKLIBRARYASSET.ZAUTHOR,       -- 1 author
30            ZBKLIBRARYASSET.ZASSETID,      -- 2 id
31            ZBKLIBRARYASSET.ZLASTOPENDATE  -- 3 last_opened
32        FROM ZBKLIBRARYASSET
33        ORDER BY ZBKLIBRARYASSET.ZTITLE;"
34    };
35
36    fn from_row(row: &Row<'_>) -> Self {
37        let last_opened: f64 = row.get_unwrap(3);
38
39        Self {
40            title: row.get_unwrap(0),
41            author: row.get_unwrap(1),
42            metadata: BookMetadata {
43                id: row.get_unwrap(2),
44                last_opened: Some(DateTimeUtc::from(last_opened)),
45            },
46        }
47    }
48}
49
50// For iOS.
51impl From<BookRaw> for Book {
52    fn from(book: BookRaw) -> Self {
53        Self {
54            title: book.title,
55            author: book.author,
56            metadata: BookMetadata {
57                id: book.id,
58                // TODO: Does iOS store the `last_opened` date?
59                last_opened: None,
60            },
61        }
62    }
63}
64
65/// A struct representing a book's metadata.
66#[derive(Debug, Default, Clone, Serialize)]
67pub struct BookMetadata {
68    /// The book's unique id.
69    pub id: String,
70
71    /// The date the book was last opened.
72    pub last_opened: Option<DateTimeUtc>,
73}