mod detection;
mod error;
mod model;
mod options;
mod parsers;
mod validation;
pub use detection::{DetectionError, detect, detect_named};
pub use error::{ErrorKind, ParseError};
pub use model::{
Category, Changelog, Entry, EntryKind, LinkDefinition, Metadata, Release, ReleaseStatus,
Section, Span,
};
pub use options::ParseOptions;
pub use validation::{Diagnostic, DiagnosticCode, Severity, validate, validate_for_format};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum Format {
#[default]
KeepAChangelog,
ConventionalChangelog,
GenericMarkdown,
#[serde(rename = "github-release-notes")]
GitHubReleaseNotes,
Changesets,
Towncrier,
DebianChangelog,
GnuNews,
#[serde(rename = "gnu-changelog")]
GnuChangeLog,
}
impl Format {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::KeepAChangelog => "keep-a-changelog",
Self::ConventionalChangelog => "conventional-changelog",
Self::GenericMarkdown => "generic-markdown",
Self::GitHubReleaseNotes => "github-release-notes",
Self::Changesets => "changesets",
Self::Towncrier => "towncrier",
Self::DebianChangelog => "debian-changelog",
Self::GnuNews => "gnu-news",
Self::GnuChangeLog => "gnu-changelog",
}
}
}
pub const MAX_INPUT_BYTES: usize = 16_777_216;
pub fn parse(input: &str, format: Format) -> Result<Changelog, ParseError> {
ParseOptions::default().parse(input, format)
}
pub fn parse_named(input: &str, format: Format, name: &str) -> Result<Changelog, ParseError> {
ParseOptions::default().parse_named(input, format, name)
}
fn parse_internal(
input: &str,
format: Format,
name: Option<&str>,
options: ParseOptions,
) -> Result<Changelog, ParseError> {
options.check_input(input)?;
if input.trim().is_empty() && !(format == Format::Towncrier && name.is_some()) {
return Err(ParseError::new(
ErrorKind::EmptyInput,
None,
"expected nonempty changelog or release-note content",
));
}
let mut changelog = match format {
Format::KeepAChangelog => parsers::keep_a_changelog::parse(input),
Format::ConventionalChangelog | Format::GenericMarkdown => {
parsers::histories::parse(input, format)
}
Format::GitHubReleaseNotes => parsers::github::parse(input),
Format::Changesets => parsers::changesets::parse(input),
Format::Towncrier => parsers::towncrier::parse(input, name),
Format::DebianChangelog => parsers::debian::parse(input),
Format::GnuNews | Format::GnuChangeLog => parsers::gnu::parse(input, format),
}?;
changelog.format = format;
Ok(changelog)
}