pinakes-core: book management foundation
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: I379005c29a79a637a8e1fc3709907cd36a6a6964
This commit is contained in:
parent
87a4482576
commit
bda36ac152
9 changed files with 420 additions and 0 deletions
|
|
@ -269,3 +269,115 @@ pub struct SavedSearch {
|
|||
pub sort_order: Option<String>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
// Book Management Types
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct BookMetadata {
|
||||
pub media_id: MediaId,
|
||||
pub isbn: Option<String>,
|
||||
pub isbn13: Option<String>,
|
||||
pub publisher: Option<String>,
|
||||
pub language: Option<String>,
|
||||
pub page_count: Option<i32>,
|
||||
pub publication_date: Option<chrono::NaiveDate>,
|
||||
pub series_name: Option<String>,
|
||||
pub series_index: Option<f64>,
|
||||
pub format: Option<String>,
|
||||
pub authors: Vec<AuthorInfo>,
|
||||
pub identifiers: HashMap<String, Vec<String>>,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct AuthorInfo {
|
||||
pub name: String,
|
||||
pub role: String,
|
||||
pub file_as: Option<String>,
|
||||
pub position: i32,
|
||||
}
|
||||
|
||||
impl AuthorInfo {
|
||||
pub fn new(name: String) -> Self {
|
||||
Self {
|
||||
name,
|
||||
role: "author".to_string(),
|
||||
file_as: None,
|
||||
position: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_role(mut self, role: String) -> Self {
|
||||
self.role = role;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_file_as(mut self, file_as: String) -> Self {
|
||||
self.file_as = Some(file_as);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_position(mut self, position: i32) -> Self {
|
||||
self.position = position;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ReadingProgress {
|
||||
pub media_id: MediaId,
|
||||
pub user_id: Uuid,
|
||||
pub current_page: i32,
|
||||
pub total_pages: Option<i32>,
|
||||
pub progress_percent: f64,
|
||||
pub last_read_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl ReadingProgress {
|
||||
pub fn new(
|
||||
media_id: MediaId,
|
||||
user_id: Uuid,
|
||||
current_page: i32,
|
||||
total_pages: Option<i32>,
|
||||
) -> Self {
|
||||
let progress_percent = if let Some(total) = total_pages {
|
||||
if total > 0 {
|
||||
(current_page as f64 / total as f64 * 100.0).min(100.0)
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
Self {
|
||||
media_id,
|
||||
user_id,
|
||||
current_page,
|
||||
total_pages,
|
||||
progress_percent,
|
||||
last_read_at: Utc::now(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ReadingStatus {
|
||||
ToRead,
|
||||
Reading,
|
||||
Completed,
|
||||
Abandoned,
|
||||
}
|
||||
|
||||
impl fmt::Display for ReadingStatus {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::ToRead => write!(f, "to_read"),
|
||||
Self::Reading => write!(f, "reading"),
|
||||
Self::Completed => write!(f, "completed"),
|
||||
Self::Abandoned => write!(f, "abandoned"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue