use handlebars::Handlebars;
use serde::{Serialize, Serializer};
use time::{macros::format_description, OffsetDateTime};
pub const TEMPLATE_CHANGELOG_STD: &str = include_str!("tpl/changelog.hbs");
pub const TEMPLATE_RELEASE_STD: &str = include_str!("tpl/release.hbs");
#[derive(Debug, Serialize)]
pub struct Changelog {
pub releases: Vec<Release>,
}
#[derive(Debug, Serialize)]
pub struct Release {
pub version: String,
#[serde(serialize_with = "serialize_date")]
pub date: OffsetDateTime,
pub url: Option<String>,
pub sections: Vec<Section>,
}
fn serialize_date<S>(date: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let format = format_description!("[year]-[month]-[day]");
date.format(&format).unwrap().serialize(serializer)
}
#[derive(Debug, Serialize)]
pub struct Section {
pub label: String,
pub items: Vec<String>,
}
impl PartialEq for Section {
fn eq(&self, other: &Self) -> bool {
self.label == other.label
}
}
impl Section {
pub fn new(label: &str) -> Self {
Self {
label: label.to_string(),
items: vec![],
}
}
}
#[derive(Debug, thiserror::Error)]
#[error("Changelog error:{0}")]
pub struct Error(String);
impl Changelog {
pub fn render(&self, template: &str) -> Result<String, Error> {
let handlebars = Handlebars::new();
handlebars
.render_template(template, &self)
.map_err(|err| Error(err.to_string()))
}
}
impl Release {
pub fn render(&self, template: &str) -> Result<String, Error> {
let handlebars = Handlebars::new();
handlebars
.render_template(template, &self)
.map_err(|err| Error(err.to_string()))
}
}