1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use crate::{
    tags::{
        Author, Dependency, Description, Export, GetTag, License, Maintainer, PackageName, Tag,
        Url, Version,
    },
    PackageError,
};
use roxmltree::Node;
use std::convert::TryFrom;

#[derive(Default, Debug, Clone, PartialEq)]
pub struct PackageCommon {
    pub name: String,
    pub version: Version,
    pub description: String,
    pub maintainer: Vec<Maintainer>,
    pub license: Vec<License>,
    pub url: Vec<Url>,
    pub author: Vec<Author>,
    pub build_depend: Vec<Dependency>,
    pub buildtool_depend: Vec<Dependency>,
    pub test_depend: Vec<Dependency>,
    pub conflict: Vec<Dependency>,
    pub replace: Vec<Dependency>,
    pub export: Option<Export>,
}

pub trait PackageCommonMethods {
    fn common(&self) -> &PackageCommon;

    fn name(&self) -> &String {
        &self.common().name
    }

    fn version(&self) -> &Version {
        &self.common().version
    }

    fn description(&self) -> &String {
        &self.common().description
    }

    fn maintainer(&self) -> &Vec<Maintainer> {
        &self.common().maintainer
    }

    fn license(&self) -> &Vec<License> {
        &self.common().license
    }

    fn url(&self) -> &Vec<Url> {
        &self.common().url
    }

    fn author(&self) -> &Vec<Author> {
        &self.common().author
    }

    fn build_depend(&self) -> &Vec<Dependency> {
        &self.common().build_depend
    }

    fn buildtool_depend(&self) -> &Vec<Dependency> {
        &self.common().buildtool_depend
    }

    fn test_depend(&self) -> &Vec<Dependency> {
        &self.common().test_depend
    }

    fn conflict(&self) -> &Vec<Dependency> {
        &self.common().conflict
    }

    fn replace(&self) -> &Vec<Dependency> {
        &self.common().replace
    }

    fn export(&self) -> &Option<Export> {
        &self.common().export
    }
}

impl TryFrom<Node<'_, '_>> for PackageCommon {
    type Error = PackageError;
    fn try_from(node: Node) -> Result<Self, Self::Error> {
        use PackageError::*;
        let name: Tag<PackageName> = node.get_tag("name").ok_or(NoName)??;
        let version: Version = node
            .get_tag("version")
            .ok_or(NoVersion)?
            .map_err(InvalidVersion)?;
        let description: Description = node.get_tag("description").ok_or(NoDescription)??;
        let maintainer: Vec<Maintainer> = node.get_tags("maintainer").map_err(InvalidMaintainer)?;
        let license: Vec<License> = node.get_tags("license").map_err(InvalidLicense)?;
        let url: Vec<Url> = node.get_tags("url").map_err(InvalidUrl)?;
        let author: Vec<Author> = node.get_tags("author").map_err(InvalidAuthor)?;
        let build_depend: Vec<Dependency> =
            node.get_tags("build_depend").map_err(InvalidDependency)?;
        let buildtool_depend: Vec<Dependency> = node
            .get_tags("buildtool_depend")
            .map_err(InvalidDependency)?;
        let test_depend: Vec<Dependency> =
            node.get_tags("test_depend").map_err(InvalidDependency)?;
        let conflict: Vec<Dependency> = node.get_tags("conflict").map_err(InvalidDependency)?;
        let replace: Vec<Dependency> = node.get_tags("replace").map_err(InvalidDependency)?;
        let export: Option<Export> = node.get_tag("export").transpose()?;

        if maintainer.is_empty() {
            return Err(NoMaintainer);
        }

        if license.is_empty() {
            return Err(NoLicense);
        }

        Ok(Self {
            name: name.to_string(),
            version,
            description: description.to_string(),
            maintainer,
            license,
            url,
            author,
            build_depend,
            buildtool_depend,
            test_depend,
            conflict,
            replace,
            export,
        })
    }
}