diff --git a/Cargo.toml b/Cargo.toml index d20d667..c0690a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ edition = "2018" [dependencies] nom = { version = "5", default-features = false, features = ["std"] } unicase = "2.5" +serde = { version = "1.0", features = ["derive"], optional = true } [dev-dependencies] indoc = "0.3" diff --git a/src/component.rs b/src/component.rs index ced2521..1c5c36d 100644 --- a/src/component.rs +++ b/src/component.rs @@ -1,10 +1,15 @@ //! Conventional Commit components. -use crate::{Error, ErrorKind}; +use std::convert::TryFrom; use std::fmt; use std::ops::Deref; use std::str::FromStr; +#[cfg(feature = "serde")] +use serde::{Deserialize, Serialize}; + +use crate::{Error, ErrorKind}; + /// A single footer. /// /// A footer is similar to a Git trailer, with the exception of not requiring @@ -66,6 +71,9 @@ impl<'a> SimpleFooter<'a> { /// The type of separator between the footer token and value. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", serde(try_from = "&str"))] +#[cfg_attr(feature = "serde", serde(into = "&'static str"))] pub enum FooterSeparator { /// ": " ColonSpace, @@ -77,10 +85,9 @@ pub enum FooterSeparator { __NonExhaustive, } -impl Deref for FooterSeparator { - type Target = str; - - fn deref(&self) -> &Self::Target { +impl FooterSeparator { + /// The string representation of the footer. + pub fn as_str(&self) -> &'static str { match self { FooterSeparator::ColonSpace => ": ", FooterSeparator::SpacePound => " #", @@ -89,6 +96,26 @@ impl Deref for FooterSeparator { } } +impl AsRef for FooterSeparator { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl Deref for FooterSeparator { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.as_str() + } +} + +impl Into<&'static str> for FooterSeparator { + fn into(self) -> &'static str { + self.as_str() + } +} + impl fmt::Display for FooterSeparator { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self) @@ -107,17 +134,30 @@ impl FromStr for FooterSeparator { } } +impl<'s> TryFrom<&'s str> for FooterSeparator { + type Error = Error; + + fn try_from(value: &str) -> Result { + value.parse() + } +} + macro_rules! components { ($($ty:ident),+) => ( $( /// A component of the conventional commit. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] - pub struct $ty<'a>(&'a str); + #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] + #[cfg_attr(feature = "serde", serde(transparent))] + pub struct $ty<'a> { + #[cfg_attr(feature = "serde", serde(borrow))] + value: &'a str + } impl<'a> $ty<'a> { /// Create a $ty pub fn new(value: &'a str) -> Self { - $ty(value) + Self { value } } } @@ -125,19 +165,19 @@ macro_rules! components { type Target = str; fn deref(&self) -> &Self::Target { - &self.0 + &self.value } } impl fmt::Display for $ty<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) + self.value.fmt(f) } } impl<'a> From<&'a str> for $ty<'a> { - fn from(string: &'a str) -> Self { - Self(string) + fn from(value: &'a str) -> Self { + Self { value } } } )+ @@ -149,12 +189,14 @@ macro_rules! unicase_components { $( /// A component of the conventional commit. #[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] - pub struct $ty<'a>(unicase::UniCase<&'a str>); + pub struct $ty<'a> { + value: unicase::UniCase<&'a str> + } impl<'a> $ty<'a> { /// Create a $ty pub fn new(value: &'a str) -> Self { - $ty(unicase::UniCase::new(value)) + Self { value: unicase::UniCase::new(value) } } } @@ -162,19 +204,19 @@ macro_rules! unicase_components { type Target = str; fn deref(&self) -> &Self::Target { - &self.0.into_inner() + &self.value.into_inner() } } impl fmt::Display for $ty<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) + self.value.fmt(f) } } impl<'a> From<&'a str> for $ty<'a> { - fn from(string: &'a str) -> Self { - Self(unicase::UniCase::new(string)) + fn from(value: &'a str) -> Self { + Self { value: unicase::UniCase::new(value) } } } )+