1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use std::{
borrow::Cow,
fmt,
fmt::{Display, Formatter},
};
/// A single contiguous block of [`CommitMessage`] text
#[derive(Debug, PartialEq, Eq, Clone, Default)]
pub struct Body<'a> {
text: Cow<'a, str>,
}
impl<'a> Body<'a> {
/// Append one [`Body`] onto another
///
/// This is for concatenating multiple [`Bodies`] together
///
/// # Example
///
/// ```
/// use indoc::indoc;
/// use mit_commit::Body;
///
/// assert_eq!(
/// Body::from(indoc!(
/// "
/// Example 1
/// Example 2"
/// )),
/// Body::from("Example 1").append(&Body::from("Example 2"))
/// )
/// ```
#[must_use]
pub fn append(&self, additional: &Self) -> Self {
Self::from(format!("{}\n{}", self.text, additional.text))
}
/// Is this [`Body`] empty
///
/// An empty [`Body`] usually indicate a paragraph break in a
/// [`CommitMessage`] so it's handy to be able to see them.
///
/// # Example
///
/// ```
/// use indoc::indoc;
/// use mit_commit::Body;
///
/// assert_eq!(Body::from("").is_empty(), true)
/// ```
#[must_use]
pub fn is_empty(&self) -> bool {
self.text.is_empty()
}
}
impl<'a> From<Cow<'a, str>> for Body<'a> {
fn from(body: Cow<'a, str>) -> Self {
Self { text: body }
}
}
impl<'a> From<&'a str> for Body<'a> {
fn from(body: &'a str) -> Self {
Self::from(Cow::Borrowed(body))
}
}
impl<'a> From<String> for Body<'a> {
fn from(body: String) -> Self {
Self::from(Cow::from(body))
}
}
impl<'a> From<Body<'a>> for String {
fn from(body: Body<'_>) -> Self {
body.text.into()
}
}
impl<'a> From<Body<'a>> for Cow<'a, str> {
fn from(body: Body<'a>) -> Self {
body.text
}
}
impl<'a> Display for Body<'a> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", String::from(self.clone()))
}
}