use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::common::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Item {
pub key: String,
pub version: u64,
pub library: Library,
#[serde(default)]
pub links: HashMap<String, LinkEntry>,
#[serde(default)]
pub meta: ItemMeta,
pub data: ItemData,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ItemMeta {
#[serde(rename = "creatorSummary")]
pub creator_summary: Option<String>,
#[serde(rename = "numChildren")]
pub num_children: Option<u64>,
#[serde(rename = "parsedDate")]
pub parsed_date: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ItemData {
pub key: String,
pub version: u64,
#[serde(rename = "itemType")]
pub item_type: String,
pub title: Option<String>,
#[serde(default)]
pub creators: Vec<Creator>,
#[serde(default)]
pub tags: Vec<ItemTag>,
#[serde(default)]
pub collections: Vec<String>,
pub relations: Option<serde_json::Value>,
#[serde(rename = "dateAdded")]
pub date_added: Option<String>,
#[serde(rename = "dateModified")]
pub date_modified: Option<String>,
#[serde(rename = "abstractNote")]
pub abstract_note: Option<String>,
#[serde(rename = "publicationTitle")]
pub publication_title: Option<String>,
pub publisher: Option<String>,
pub place: Option<String>,
pub date: Option<String>,
pub volume: Option<String>,
pub issue: Option<String>,
pub pages: Option<String>,
pub series: Option<String>,
#[serde(rename = "seriesTitle")]
pub series_title: Option<String>,
#[serde(rename = "seriesText")]
pub series_text: Option<String>,
#[serde(rename = "journalAbbreviation")]
pub journal_abbreviation: Option<String>,
#[serde(rename = "DOI")]
pub doi: Option<String>,
#[serde(rename = "citationKey")]
pub citation_key: Option<String>,
pub url: Option<String>,
#[serde(rename = "accessDate")]
pub access_date: Option<String>,
pub archive: Option<String>,
#[serde(rename = "archiveLocation")]
pub archive_location: Option<String>,
#[serde(rename = "shortTitle")]
pub short_title: Option<String>,
pub language: Option<String>,
#[serde(rename = "libraryCatalog")]
pub library_catalog: Option<String>,
#[serde(rename = "callNumber")]
pub call_number: Option<String>,
pub rights: Option<String>,
pub extra: Option<String>,
#[serde(rename = "ISBN")]
pub isbn: Option<String>,
#[serde(rename = "ISSN")]
pub issn: Option<String>,
#[serde(rename = "PMID")]
pub pmid: Option<String>,
#[serde(rename = "PMCID")]
pub pmcid: Option<String>,
#[serde(rename = "parentItem")]
pub parent_item: Option<String>,
#[serde(rename = "linkMode")]
pub link_mode: Option<String>,
#[serde(rename = "contentType")]
pub content_type: Option<String>,
pub charset: Option<String>,
pub filename: Option<String>,
pub md5: Option<String>,
pub mtime: Option<u64>,
pub note: Option<String>,
pub section: Option<String>,
#[serde(rename = "partNumber")]
pub part_number: Option<String>,
#[serde(rename = "partTitle")]
pub part_title: Option<String>,
#[serde(flatten)]
pub extra_fields: HashMap<String, serde_json::Value>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_deserialize_item_fixture() {
let json = include_str!("../../tests/fixtures/item.json");
let item: Item = serde_json::from_str(json).unwrap();
assert_eq!(item.key, "LF4MJWZK");
assert_eq!(item.data.item_type, "journalArticle");
assert_eq!(item.data.title.as_deref(), Some("Real-Time Rendering 4th: Ray Tracing"));
assert_eq!(item.data.creators.len(), 6);
assert_eq!(item.data.creators[0].creator_type, "author");
assert_eq!(item.data.creators[0].last_name.as_deref(), Some("Akenine-Moller"));
}
#[test]
fn test_deserialize_attachment_fixture() {
let json = include_str!("../../tests/fixtures/attachment.json");
let item: Item = serde_json::from_str(json).unwrap();
assert_eq!(item.data.item_type, "attachment");
assert_eq!(item.data.link_mode.as_deref(), Some("imported_file"));
assert!(item.data.filename.is_some());
}
}