pubmed_parser/europe_pmc/
models.rs

1//! Domain models for Europe PMC REST API JSON responses.
2//!
3//! These mirror the item-level shapes returned by the Europe PMC RESTful Web
4//! Service (<https://europepmc.org/RestfulWebService>). They are intentionally
5//! lenient: unknown or rarely-used fields are captured in an `extra` map rather
6//! than modelled exhaustively, so new API fields never break deserialization.
7
8use serde::{Deserialize, Serialize};
9
10use super::de::opt_string_flex;
11
12/// A single search result record from the Europe PMC `search` endpoint.
13///
14/// Field coverage matches `resultType=lite`; `resultType=core` adds many more
15/// fields which are preserved in [`EuropePmcResult::extra`].
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
17#[serde(rename_all = "camelCase")]
18pub struct EuropePmcResult {
19    /// Record identifier within its source database (e.g. a PMID for `MED`).
20    #[serde(default)]
21    pub id: String,
22    /// Source database code (`MED`, `PMC`, `PPR`, `AGR`, `CBA`, `PAT`, ...).
23    #[serde(default)]
24    pub source: String,
25    /// PubMed ID, when the record is linked to PubMed.
26    #[serde(default)]
27    pub pmid: Option<String>,
28    /// PubMed Central ID (e.g. `PMC7894017`), when full text is in PMC.
29    #[serde(default)]
30    pub pmcid: Option<String>,
31    /// Digital Object Identifier.
32    #[serde(default)]
33    pub doi: Option<String>,
34    /// Article title.
35    #[serde(default)]
36    pub title: Option<String>,
37    /// Comma-separated author list, as provided by Europe PMC.
38    #[serde(default)]
39    pub author_string: Option<String>,
40    /// Journal title.
41    #[serde(default)]
42    pub journal_title: Option<String>,
43    /// Publication year.
44    #[serde(default, deserialize_with = "opt_string_flex")]
45    pub pub_year: Option<String>,
46    /// Open access flag (`"Y"` / `"N"`).
47    #[serde(default)]
48    pub is_open_access: Option<String>,
49    /// Any additional fields not modelled above (populated for `resultType=core`).
50    #[serde(flatten, default)]
51    pub extra: serde_json::Map<String, serde_json::Value>,
52}
53
54/// A cited reference from the Europe PMC `references` endpoint.
55#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
56#[serde(rename_all = "camelCase")]
57pub struct EuropePmcReference {
58    /// Source database code of the referenced record, when matched.
59    #[serde(default)]
60    pub source: Option<String>,
61    /// Identifier of the referenced record, when matched.
62    #[serde(default, deserialize_with = "opt_string_flex")]
63    pub id: Option<String>,
64    /// Citation type (e.g. `"JOURNAL ARTICLE"`).
65    #[serde(default)]
66    pub citation_type: Option<String>,
67    /// Title of the cited work.
68    #[serde(default)]
69    pub title: Option<String>,
70    /// Comma-separated author list of the cited work.
71    #[serde(default)]
72    pub author_string: Option<String>,
73    /// Abbreviated journal name.
74    #[serde(default)]
75    pub journal_abbreviation: Option<String>,
76    /// Publication year.
77    #[serde(default, deserialize_with = "opt_string_flex")]
78    pub pub_year: Option<String>,
79    /// Journal volume.
80    #[serde(default)]
81    pub volume: Option<String>,
82    /// Journal issue.
83    #[serde(default)]
84    pub issue: Option<String>,
85    /// Page range / location.
86    #[serde(default)]
87    pub page_info: Option<String>,
88    /// PubMed ID of the cited work, when matched.
89    #[serde(default, deserialize_with = "opt_string_flex")]
90    pub pmid: Option<String>,
91    /// DOI of the cited work, when present.
92    #[serde(default)]
93    pub doi: Option<String>,
94    /// Any additional fields not modelled above.
95    #[serde(flatten, default)]
96    pub extra: serde_json::Map<String, serde_json::Value>,
97}
98
99/// A citing article from the Europe PMC `citations` endpoint.
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
101#[serde(rename_all = "camelCase")]
102pub struct EuropePmcCitation {
103    /// Identifier of the citing record within its source database.
104    #[serde(default, deserialize_with = "opt_string_flex")]
105    pub id: Option<String>,
106    /// Source database code of the citing record.
107    #[serde(default)]
108    pub source: Option<String>,
109    /// Citation type (e.g. `"JOURNAL ARTICLE"`).
110    #[serde(default)]
111    pub citation_type: Option<String>,
112    /// Title of the citing article.
113    #[serde(default)]
114    pub title: Option<String>,
115    /// Comma-separated author list of the citing article.
116    #[serde(default)]
117    pub author_string: Option<String>,
118    /// Abbreviated journal name.
119    #[serde(default)]
120    pub journal_abbreviation: Option<String>,
121    /// Publication year.
122    #[serde(default, deserialize_with = "opt_string_flex")]
123    pub pub_year: Option<String>,
124    /// Journal volume.
125    #[serde(default)]
126    pub volume: Option<String>,
127    /// Journal issue.
128    #[serde(default)]
129    pub issue: Option<String>,
130    /// Page range / location.
131    #[serde(default)]
132    pub page_info: Option<String>,
133    /// Number of times the citing article has itself been cited.
134    #[serde(default, deserialize_with = "opt_string_flex")]
135    pub cited_by_count: Option<String>,
136    /// Any additional fields not modelled above.
137    #[serde(flatten, default)]
138    pub extra: serde_json::Map<String, serde_json::Value>,
139}
140
141/// A grouping of cross-references to a single external database from the
142/// Europe PMC `databaseLinks` endpoint.
143#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
144#[serde(rename_all = "camelCase")]
145pub struct EuropePmcDatabaseLink {
146    /// External database name (e.g. `"UNIPROT"`, `"EMBL"`, `"PDB"`).
147    #[serde(default)]
148    pub db_name: Option<String>,
149    /// Number of cross-references to this database.
150    #[serde(default)]
151    pub db_count: Option<u32>,
152    /// Individual cross-reference entries.
153    #[serde(rename = "dbCrossReferenceInfo", default)]
154    pub info: Vec<EuropePmcDbCrossReferenceInfo>,
155}
156
157/// A single external-database cross-reference entry. The meaning of each `info`
158/// slot varies by database; Europe PMC documents them only positionally.
159#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
160pub struct EuropePmcDbCrossReferenceInfo {
161    /// First positional value (often the external accession/identifier).
162    #[serde(default)]
163    pub info1: Option<String>,
164    /// Second positional value.
165    #[serde(default)]
166    pub info2: Option<String>,
167    /// Third positional value.
168    #[serde(default)]
169    pub info3: Option<String>,
170    /// Fourth positional value.
171    #[serde(default)]
172    pub info4: Option<String>,
173}