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<'a> Comments<'a> {
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<'a> From<Comments<'a>> 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}