use itertools::Itertools;
use log::warn;
pub mod license;
pub mod wxs;
use crate::Error;
use crate::Result;
use log::trace;
use regex::Regex;
use std::fs::File;
use std::io::{self, Write};
use std::path::PathBuf;
use cargo_metadata::Package;
pub struct RenderOutput {
pub path: Option<PathBuf>,
pub rendered: String,
}
impl RenderOutput {
pub fn write(&self) -> Result<()> {
let mut out = destination(self.path.as_ref())?;
out.write_all(self.rendered.as_bytes())?;
out.flush()?;
Ok(())
}
pub fn write_disk_only(&self) -> Result<()> {
if self.path.is_none() {
warn!("License.rtf also needs to be generated!");
return Ok(());
}
self.write()
}
}
fn destination(output: Option<&PathBuf>) -> Result<Box<dyn Write>> {
if let Some(ref output) = output {
trace!("An output path has been explicitly specified");
let f = File::create(output)?;
Ok(Box::new(f))
} else {
trace!(
"An output path has NOT been explicitly specified. Implicitly \
determine output."
);
Ok(Box::new(io::stdout()))
}
}
fn authors(package: &Package) -> Result<String> {
let result = package
.authors
.iter()
.map(|s| {
let re = Regex::new(r"<(.*?)>").unwrap();
re.replace_all(s, "")
})
.map(|s| String::from(s.trim()))
.join("; ");
if result.is_empty() {
Err(Error::Manifest("authors"))
} else {
Ok(result)
}
}
#[cfg(test)]
mod tests {
use super::*;
const SINGLE_AUTHOR_MANIFEST: &str = r#"{
"name": "Example",
"version": "0.1.0",
"authors": ["First Last <first.last@example.com>"],
"id": "",
"dependencies": [],
"targets": [],
"features": {},
"manifest_path": ""
}"#;
const MULTIPLE_AUTHORS_MANIFEST: &str = r#"{
"name": "Example",
"version": "0.1.0",
"authors": ["1 Author <first.last@example.com>", "2 Author <2.author@example.com>", "3 author <3.author@example.com>"],
"id": "",
"dependencies": [],
"targets": [],
"features": {},
"manifest_path": ""
}"#;
#[test]
fn authors_with_single_author_works() {
let manifest = serde_json::from_str(SINGLE_AUTHOR_MANIFEST).expect("Parsing TOML");
let actual = authors(&manifest).unwrap();
assert_eq!(actual, String::from("First Last"));
}
#[test]
fn authors_with_multiple_authors_works() {
let manifest = serde_json::from_str(MULTIPLE_AUTHORS_MANIFEST).expect("Parsing TOML");
let actual = authors(&manifest).unwrap();
assert_eq!(actual, String::from("1 Author; 2 Author; 3 author"));
}
}