use crate::release::Release;
use std::collections::BTreeMap;
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Changelog {
pub(crate) title: String,
pub(crate) description: Option<String>,
releases: BTreeMap<Option<semver::Version>, Release>,
pub(crate) keep_a_changelog_message: bool,
pub(crate) semantic_versioning_message: bool,
}
impl Changelog {
pub fn new(title: impl ToString) -> Self {
Self {
title: title.to_string(),
description: None,
releases: Default::default(),
keep_a_changelog_message: false,
semantic_versioning_message: false,
}
}
pub fn with_description(self, description: impl ToString) -> Self {
Self {
description: Some(description.to_string()),
..self
}
}
pub fn add_release(self, release: Release) -> Self {
let mut releases = self.releases;
releases.insert(release.version.clone(), release);
Self { releases, ..self }
}
pub fn add_keep_a_changelog_message(self) -> Self {
Self {
keep_a_changelog_message: true,
..self
}
}
pub fn add_semantic_versioning_message(self) -> Self {
Self {
semantic_versioning_message: true,
..self
}
}
pub fn releases(&self) -> impl Iterator<Item = &Release> {
self.releases.values()
}
pub fn versions(&self) -> impl Iterator<Item = &semver::Version> {
self.releases.keys().filter_map(|v| v.as_ref())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ensure_releases_are_sorted_by_version_number() {
let changelog = Changelog::new("")
.add_release(Release::new(0, 2, 0))
.add_release(Release::new(0, 1, 0))
.add_release(Release::new(0, 1, 1))
.add_release(Release::unreleased())
.add_release(Release::new(0, 2, 1))
.add_release(Release::new(0, 1, 2));
assert_eq!(
changelog
.releases()
.map(|v| v.version.clone())
.collect::<Vec<_>>(),
vec![
None,
Some(semver::Version::new(0, 1, 0)),
Some(semver::Version::new(0, 1, 1)),
Some(semver::Version::new(0, 1, 2)),
Some(semver::Version::new(0, 2, 0)),
Some(semver::Version::new(0, 2, 1)),
]
);
assert_eq!(
changelog.versions().cloned().collect::<Vec<_>>(),
vec![
semver::Version::new(0, 1, 0),
semver::Version::new(0, 1, 1),
semver::Version::new(0, 1, 2),
semver::Version::new(0, 2, 0),
semver::Version::new(0, 2, 1),
]
);
}
}