mit_commit/
comments.rs

1use std::slice::Iter;
2
3use crate::{comment::Comment, fragment::Fragment};
4
5/// A collection of comments from a [`CommitMessage`]
6#[derive(Debug, PartialEq, Eq, Clone, Default)]
7pub struct Comments<'a> {
8    comments: Vec<Comment<'a>>,
9}
10
11impl Comments<'_> {
12    /// Iterate over the [`Comment`] in the [`Comments`]
13    ///
14    /// # Examples
15    ///
16    /// ```
17    /// use mit_commit::{Comment, Comments};
18    ///
19    /// let trailers = Comments::from(vec![
20    ///     Comment::from("# Comment 1"),
21    ///     Comment::from("# Comment 2"),
22    ///     Comment::from("# Comment 3"),
23    /// ]);
24    /// let mut iterator = trailers.iter();
25    ///
26    /// assert_eq!(iterator.next(), Some(&Comment::from("# Comment 1")));
27    /// assert_eq!(iterator.next(), Some(&Comment::from("# Comment 2")));
28    /// assert_eq!(iterator.next(), Some(&Comment::from("# Comment 3")));
29    /// assert_eq!(iterator.next(), None);
30    /// ```
31    pub fn iter(&self) -> Iter<'_, Comment<'_>> {
32        self.comments.iter()
33    }
34}
35
36impl<'a> IntoIterator for Comments<'a> {
37    type IntoIter = std::vec::IntoIter<Comment<'a>>;
38    type Item = Comment<'a>;
39
40    /// Iterate over the [`Comment`] in the [`Comments`]
41    ///
42    /// # Examples
43    ///
44    /// ```
45    /// use mit_commit::{Comment, Comments};
46    ///
47    /// let trailers = Comments::from(vec![
48    ///     Comment::from("# Comment 1"),
49    ///     Comment::from("# Comment 2"),
50    ///     Comment::from("# Comment 3"),
51    /// ]);
52    /// let mut iterator = trailers.into_iter();
53    ///
54    /// assert_eq!(iterator.next(), Some(Comment::from("# Comment 1")));
55    /// assert_eq!(iterator.next(), Some(Comment::from("# Comment 2")));
56    /// assert_eq!(iterator.next(), Some(Comment::from("# Comment 3")));
57    /// assert_eq!(iterator.next(), None);
58    /// ```
59    fn into_iter(self) -> Self::IntoIter {
60        self.comments.into_iter()
61    }
62}
63
64impl<'a> IntoIterator for &'a Comments<'a> {
65    type IntoIter = Iter<'a, Comment<'a>>;
66    type Item = &'a Comment<'a>;
67
68    /// Iterate over the [`Comment`] in the [`Comments`]
69    ///
70    /// # Examples
71    ///
72    /// ```
73    /// use std::borrow::Borrow;
74    ///
75    /// use mit_commit::{Comment, Comments};
76    ///
77    /// let comments = Comments::from(vec![
78    ///     Comment::from("# Comment 1"),
79    ///     Comment::from("# Comment 2"),
80    ///     Comment::from("# Comment 3"),
81    /// ]);
82    /// let comments_ref = comments.borrow();
83    /// let mut iterator = comments_ref.into_iter();
84    ///
85    /// assert_eq!(iterator.next(), Some(&Comment::from("# Comment 1")));
86    /// assert_eq!(iterator.next(), Some(&Comment::from("# Comment 2")));
87    /// assert_eq!(iterator.next(), Some(&Comment::from("# Comment 3")));
88    /// assert_eq!(iterator.next(), None);
89    /// ```
90    fn into_iter(self) -> Self::IntoIter {
91        self.comments.iter()
92    }
93}
94
95impl<'a> From<Vec<Comment<'a>>> for Comments<'a> {
96    fn from(comments: Vec<Comment<'a>>) -> Self {
97        Self { comments }
98    }
99}
100
101impl From<Comments<'_>> for String {
102    fn from(comments: Comments<'_>) -> Self {
103        comments
104            .comments
105            .into_iter()
106            .map(Self::from)
107            .collect::<Vec<_>>()
108            .join("\n\n")
109    }
110}
111
112impl<'a> From<Vec<Fragment<'a>>> for Comments<'a> {
113    fn from(ast: Vec<Fragment<'a>>) -> Self {
114        ast.into_iter()
115            .filter_map(|values| {
116                if let Fragment::Comment(comment) = values {
117                    Some(comment)
118                } else {
119                    None
120                }
121            })
122            .collect::<Vec<Comment<'_>>>()
123            .into()
124    }
125}