pubmed 0.2.1

A wrapper around the PubMed API
Documentation
use serde::{Deserialize, Serialize};

use crate::helpers::missing_tag_warning;
use crate::types::affiliation_info::AffiliationInfo;
use crate::types::identifier::Identifier;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Author {
    pub last_name: Option<String>,
    pub fore_name: Option<String>,
    pub initials: Option<String>,
    pub suffix: Option<String>,
    pub collective_name: Option<String>,
    pub affiliation_info: Option<AffiliationInfo>,
    pub identifiers: Vec<Identifier>,
    pub valid: bool,
}

impl Author {
    #[must_use] 
    pub fn new_from_xml(node: &roxmltree::Node) -> Self {
        let mut ret = Self {
            last_name: None,
            fore_name: None,
            initials: None,
            suffix: None,
            collective_name: None,
            affiliation_info: None,
            identifiers: vec![],
            valid: node.attribute("ValidYN") == Some("Y"),
        };
        for n in node.children().filter(roxmltree::Node::is_element) {
            match n.tag_name().name() {
                "LastName" => ret.last_name = n.text().map(std::string::ToString::to_string),
                "ForeName" => ret.fore_name = n.text().map(std::string::ToString::to_string),
                "CollectiveName" => ret.collective_name = n.text().map(std::string::ToString::to_string),
                "Initials" => ret.initials = n.text().map(std::string::ToString::to_string),
                "Suffix" => ret.suffix = n.text().map(std::string::ToString::to_string),
                "Identifier" => ret.identifiers.push(Identifier::new_from_xml(&n)),
                "AffiliationInfo" => ret.affiliation_info = Some(AffiliationInfo::new_from_xml(&n)),
                x => missing_tag_warning(&format!("Not covered in Author: '{x}'")),
            }
        }
        ret
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthorList {
    pub authors: Vec<Author>,
    pub complete: bool,
}

impl AuthorList {
    #[must_use] 
    pub fn new_from_xml(node: &roxmltree::Node) -> Self {
        Self {
            complete: node.attribute("CompleteYN") == Some("Y"),
            authors: node
                .descendants()
                .filter(|n| n.is_element() && n.tag_name().name() == "Author")
                .map(|n| Author::new_from_xml(&n))
                .collect(),
        }
    }
}