use std::{convert::TryFrom, io};
use cargo::core::Package;
use serde::Serialize;
use thiserror::Error;
use xml_writer::XmlWriter;
use crate::traits::ToXml;
#[derive(Serialize)]
#[serde(rename_all = "lowercase")]
pub struct License {
pub expression: String,
}
impl<'a> TryFrom<&'a Package> for License {
type Error = LicenseError;
fn try_from(pkg: &'a Package) -> Result<Self, Self::Error> {
let expression = pkg
.manifest()
.metadata()
.license
.as_ref()
.ok_or(LicenseError::NoLicenseProvidedError)?
.to_string();
Ok(Self { expression })
}
}
#[derive(Debug, Error)]
pub enum LicenseError {
#[error("No license was found in the package manifest")]
NoLicenseProvidedError,
}
impl<'a> TryFrom<&'a cargo_metadata::Package> for License {
type Error = LicenseError;
fn try_from(pkg: &'a cargo_metadata::Package) -> Result<Self, Self::Error> {
let expression = pkg
.license
.as_ref()
.ok_or(LicenseError::NoLicenseProvidedError)?
.to_string();
Ok(Self { expression })
}
}
impl ToXml for License {
fn to_xml<W: io::Write>(&self, xml: &mut XmlWriter<W>) -> io::Result<()> {
xml.begin_elem("license")?;
xml.begin_elem("expression")?;
xml.text(self.expression.trim())?;
xml.end_elem()?;
xml.end_elem()
}
}
impl ToXml for Vec<License> {
fn to_xml<W: io::Write>(&self, xml: &mut XmlWriter<W>) -> io::Result<()> {
if !self.is_empty() {
xml.begin_elem("licenses")?;
for license in self {
license.to_xml(xml)?;
}
xml.end_elem()?;
}
Ok(())
}
}