use {
chrono::{DateTime, Local},
std::{borrow::Cow, io::Write},
};
#[derive(Clone, Debug)]
pub struct ChangelogEntry<'a> {
pub package: Cow<'a, str>,
pub version: Cow<'a, str>,
pub distributions: Vec<Cow<'a, str>>,
pub urgency: Cow<'a, str>,
pub details: Cow<'a, str>,
pub maintainer_name: Cow<'a, str>,
pub maintainer_email: Cow<'a, str>,
pub date: DateTime<Local>,
}
impl<'a> ChangelogEntry<'a> {
pub fn write<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
writer.write_all(self.package.as_bytes())?;
writer.write_all(b" (")?;
writer.write_all(self.version.as_bytes())?;
writer.write_all(b") ")?;
writer.write_all(self.distributions.join(" ").as_bytes())?;
writer.write_all(b"; urgency=")?;
writer.write_all(self.urgency.as_bytes())?;
writer.write_all(b"\n\n")?;
writer.write_all(self.details.as_bytes())?;
writer.write_all(b"\n")?;
writer.write_all(b"-- ")?;
writer.write_all(self.maintainer_name.as_bytes())?;
writer.write_all(b" <")?;
writer.write_all(self.maintainer_email.as_bytes())?;
writer.write_all(b"> ")?;
writer.write_all(self.date.to_rfc2822().as_bytes())?;
writer.write_all(b"\n\n")?;
Ok(())
}
}
#[derive(Default)]
pub struct Changelog<'a> {
entries: Vec<ChangelogEntry<'a>>,
}
impl<'a> Changelog<'a> {
pub fn add_entry<'b: 'a>(&mut self, entry: ChangelogEntry<'b>) {
self.entries.push(entry)
}
pub fn write<W: Write>(&self, writer: &mut W) -> std::io::Result<()> {
for entry in &self.entries {
entry.write(writer)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use {super::*, crate::error::Result};
#[test]
fn test_write() -> Result<()> {
let mut changelog = Changelog::default();
changelog.add_entry(ChangelogEntry {
package: "mypackage".into(),
version: "0.1".into(),
distributions: vec!["mydist".into()],
urgency: "low".into(),
details: "details".into(),
maintainer_name: "maintainer".into(),
maintainer_email: "me@example.com".into(),
date: DateTime::from_naive_utc_and_offset(
chrono::DateTime::from_timestamp(1420000000, 0)
.unwrap()
.naive_utc(),
chrono::TimeZone::from_offset(&chrono::FixedOffset::west_opt(3600 * 7).unwrap()),
),
});
let mut buf = vec![];
changelog.write(&mut buf)?;
let s = String::from_utf8(buf).unwrap();
assert_eq!(s, "mypackage (0.1) mydist; urgency=low\n\ndetails\n-- maintainer <me@example.com> Tue, 30 Dec 2014 21:26:40 -0700\n\n");
Ok(())
}
}