Skip to content

Commit 0d91df2

Browse files
committed
WIP serde support
1 parent c4c6c06 commit 0d91df2

File tree

2 files changed

+60
-17
lines changed

2 files changed

+60
-17
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ edition = "2018"
1313
[dependencies]
1414
nom = { version = "5", default-features = false, features = ["std"] }
1515
unicase = "2.5"
16+
serde = { version = "1.0", features = ["derive"], optional = true }
1617

1718
[dev-dependencies]
1819
indoc = "0.3"

src/component.rs

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
//! Conventional Commit components.
22
3-
use crate::{Error, ErrorKind};
3+
use std::convert::TryFrom;
44
use std::fmt;
55
use std::ops::Deref;
66
use std::str::FromStr;
77

8+
#[cfg(feature = "serde")]
9+
use serde::{Deserialize, Serialize};
10+
11+
use crate::{Error, ErrorKind};
12+
813
/// A single footer.
914
///
1015
/// A footer is similar to a Git trailer, with the exception of not requiring
@@ -66,6 +71,9 @@ impl<'a> SimpleFooter<'a> {
6671

6772
/// The type of separator between the footer token and value.
6873
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
74+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
75+
#[cfg_attr(feature = "serde", serde(try_from = "&str"))]
76+
#[cfg_attr(feature = "serde", serde(into = "&'static str"))]
6977
pub enum FooterSeparator {
7078
/// ": "
7179
ColonSpace,
@@ -77,10 +85,9 @@ pub enum FooterSeparator {
7785
__NonExhaustive,
7886
}
7987

80-
impl Deref for FooterSeparator {
81-
type Target = str;
82-
83-
fn deref(&self) -> &Self::Target {
88+
impl FooterSeparator {
89+
/// The string representation of the footer.
90+
pub fn as_str(&self) -> &'static str {
8491
match self {
8592
FooterSeparator::ColonSpace => ": ",
8693
FooterSeparator::SpacePound => " #",
@@ -89,6 +96,26 @@ impl Deref for FooterSeparator {
8996
}
9097
}
9198

99+
impl AsRef<str> for FooterSeparator {
100+
fn as_ref(&self) -> &str {
101+
self.as_str()
102+
}
103+
}
104+
105+
impl Deref for FooterSeparator {
106+
type Target = str;
107+
108+
fn deref(&self) -> &Self::Target {
109+
self.as_str()
110+
}
111+
}
112+
113+
impl Into<&'static str> for FooterSeparator {
114+
fn into(self) -> &'static str {
115+
self.as_str()
116+
}
117+
}
118+
92119
impl fmt::Display for FooterSeparator {
93120
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94121
f.write_str(self)
@@ -107,37 +134,50 @@ impl FromStr for FooterSeparator {
107134
}
108135
}
109136

137+
impl<'s> TryFrom<&'s str> for FooterSeparator {
138+
type Error = Error;
139+
140+
fn try_from(value: &str) -> Result<Self, Self::Error> {
141+
value.parse()
142+
}
143+
}
144+
110145
macro_rules! components {
111146
($($ty:ident),+) => (
112147
$(
113148
/// A component of the conventional commit.
114149
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
115-
pub struct $ty<'a>(&'a str);
150+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
151+
#[cfg_attr(feature = "serde", serde(transparent))]
152+
pub struct $ty<'a> {
153+
#[cfg_attr(feature = "serde", serde(borrow))]
154+
value: &'a str
155+
}
116156

117157
impl<'a> $ty<'a> {
118158
/// Create a $ty
119159
pub fn new(value: &'a str) -> Self {
120-
$ty(value)
160+
Self { value }
121161
}
122162
}
123163

124164
impl Deref for $ty<'_> {
125165
type Target = str;
126166

127167
fn deref(&self) -> &Self::Target {
128-
&self.0
168+
&self.value
129169
}
130170
}
131171

132172
impl fmt::Display for $ty<'_> {
133173
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134-
self.0.fmt(f)
174+
self.value.fmt(f)
135175
}
136176
}
137177

138178
impl<'a> From<&'a str> for $ty<'a> {
139-
fn from(string: &'a str) -> Self {
140-
Self(string)
179+
fn from(value: &'a str) -> Self {
180+
Self { value }
141181
}
142182
}
143183
)+
@@ -149,32 +189,34 @@ macro_rules! unicase_components {
149189
$(
150190
/// A component of the conventional commit.
151191
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
152-
pub struct $ty<'a>(unicase::UniCase<&'a str>);
192+
pub struct $ty<'a> {
193+
value: unicase::UniCase<&'a str>
194+
}
153195

154196
impl<'a> $ty<'a> {
155197
/// Create a $ty
156198
pub fn new(value: &'a str) -> Self {
157-
$ty(unicase::UniCase::new(value))
199+
Self { value: unicase::UniCase::new(value) }
158200
}
159201
}
160202

161203
impl Deref for $ty<'_> {
162204
type Target = str;
163205

164206
fn deref(&self) -> &Self::Target {
165-
&self.0.into_inner()
207+
&self.value.into_inner()
166208
}
167209
}
168210

169211
impl fmt::Display for $ty<'_> {
170212
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
171-
self.0.fmt(f)
213+
self.value.fmt(f)
172214
}
173215
}
174216

175217
impl<'a> From<&'a str> for $ty<'a> {
176-
fn from(string: &'a str) -> Self {
177-
Self(unicase::UniCase::new(string))
218+
fn from(value: &'a str) -> Self {
219+
Self { value: unicase::UniCase::new(value) }
178220
}
179221
}
180222
)+

0 commit comments

Comments
 (0)