Skip to content

Commit

Permalink
WIP feat: serde support
Browse files Browse the repository at this point in the history
My main motivation is that for `committed`, I'd like to have approved
`type`s in my config format.
  • Loading branch information
epage committed Nov 16, 2019
1 parent c4c6c06 commit 93fc32e
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 17 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
76 changes: 59 additions & 17 deletions src/component.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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 => " #",
Expand All @@ -89,6 +96,26 @@ impl Deref for FooterSeparator {
}
}

impl AsRef<str> 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)
Expand All @@ -107,37 +134,50 @@ impl FromStr for FooterSeparator {
}
}

impl<'s> TryFrom<&'s str> for FooterSeparator {
type Error = Error;

fn try_from(value: &str) -> Result<Self, Self::Error> {
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 }
}
}

impl Deref for $ty<'_> {
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 }
}
}
)+
Expand All @@ -149,32 +189,34 @@ 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) }
}
}

impl Deref for $ty<'_> {
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) }
}
}
)+
Expand Down

0 comments on commit 93fc32e

Please sign in to comment.