pubmed_parser/europe_pmc/
links.rs

1//! Europe PMC `databaseLinks` endpoint response parsing.
2
3use serde::{Deserialize, Serialize};
4
5use crate::error::Result;
6
7use super::models::EuropePmcDatabaseLink;
8
9/// Parsed response from the Europe PMC `databaseLinks` endpoint (one page).
10#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
11#[serde(from = "RawDatabaseLinksResponse")]
12pub struct EuropePmcDatabaseLinkList {
13    /// Total number of cross-reference groups (across all pages).
14    pub hit_count: u64,
15    /// Cross-reference groups, one per external database.
16    pub links: Vec<EuropePmcDatabaseLink>,
17}
18
19#[derive(Deserialize)]
20#[serde(rename_all = "camelCase")]
21struct RawDatabaseLinksResponse {
22    #[serde(default)]
23    hit_count: u64,
24    #[serde(default)]
25    db_cross_reference_list: RawDbCrossReferenceList,
26}
27
28#[derive(Deserialize, Default)]
29#[serde(rename_all = "camelCase")]
30struct RawDbCrossReferenceList {
31    #[serde(default)]
32    db_cross_reference: Vec<EuropePmcDatabaseLink>,
33}
34
35impl From<RawDatabaseLinksResponse> for EuropePmcDatabaseLinkList {
36    fn from(raw: RawDatabaseLinksResponse) -> Self {
37        Self {
38            hit_count: raw.hit_count,
39            links: raw.db_cross_reference_list.db_cross_reference,
40        }
41    }
42}
43
44/// Parse a Europe PMC `databaseLinks` JSON response.
45pub fn parse_database_links_response(json: &str) -> Result<EuropePmcDatabaseLinkList> {
46    Ok(serde_json::from_str(json)?)
47}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52
53    #[test]
54    fn test_parse_database_links() {
55        let json = r#"{
56            "hitCount": 1,
57            "dbCrossReferenceList": {
58                "dbCrossReference": [
59                    {
60                        "dbName": "UNIPROT",
61                        "dbCount": 2,
62                        "dbCrossReferenceInfo": [
63                            {"info1": "P12345", "info2": "PROT1_HUMAN"},
64                            {"info1": "Q67890"}
65                        ]
66                    }
67                ]
68            }
69        }"#;
70
71        let resp = parse_database_links_response(json).unwrap();
72        assert_eq!(resp.hit_count, 1);
73        assert_eq!(resp.links.len(), 1);
74        let link = &resp.links[0];
75        assert_eq!(link.db_name.as_deref(), Some("UNIPROT"));
76        assert_eq!(link.db_count, Some(2));
77        assert_eq!(link.info.len(), 2);
78        assert_eq!(link.info[0].info1.as_deref(), Some("P12345"));
79        assert_eq!(link.info[0].info2.as_deref(), Some("PROT1_HUMAN"));
80        assert_eq!(link.info[1].info1.as_deref(), Some("Q67890"));
81    }
82}