commitlint_rs/rule/
body_max_length.rs1use crate::{message::Message, result::Violation, rule::Rule};
2use serde::{Deserialize, Serialize};
3
4use super::Level;
5
6#[derive(Clone, Debug, Deserialize, Serialize)]
8#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
9pub struct BodyMaxLength {
10 level: Option<Level>,
15
16 length: usize,
18}
19
20impl Rule for BodyMaxLength {
22 const NAME: &'static str = "body-max-length";
23 const LEVEL: Level = Level::Error;
24
25 fn message(&self, _message: &Message) -> String {
26 format!("body is longer than {} characters", self.length)
27 }
28
29 fn validate(&self, message: &Message) -> Option<Violation> {
30 if let Some(body) = &message.body {
31 if body.len() >= self.length {
32 return Some(Violation {
33 level: self.level.unwrap_or(Self::LEVEL),
34 message: self.message(message),
35 });
36 }
37 }
38
39 None
40 }
41}
42
43impl Default for BodyMaxLength {
45 fn default() -> Self {
46 Self {
47 level: Some(Self::LEVEL),
48 length: 72,
49 }
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_long_body() {
59 let rule = BodyMaxLength {
60 length: usize::MAX, ..Default::default()
62 };
63 let message = Message {
64 body: Some("Hello world".to_string()),
65 description: Some("broadcast $destroy event on scope destruction".to_string()),
66 footers: None,
67 r#type: Some("feat".to_string()),
68 raw: "feat(scope): broadcast $destroy event on scope destruction
69
70Hey!"
71 .to_string(),
72 scope: Some("scope".to_string()),
73 subject: Some("feat(scope): broadcast $destroy event on scope destruction".to_string()),
74 };
75
76 assert!(rule.validate(&message).is_none());
77 }
78
79 #[test]
80 fn test_no_body() {
81 let rule = BodyMaxLength {
82 length: usize::MAX, ..Default::default()
84 };
85 let message = Message {
86 body: None,
87 description: Some("broadcast $destroy event on scope destruction".to_string()),
88 footers: None,
89 r#type: Some("feat".to_string()),
90 raw: "feat(scope): broadcast $destroy event on scope destruction".to_string(),
91 scope: Some("scope".to_string()),
92 subject: Some("feat(scope): broadcast $destroy event on scope destruction".to_string()),
93 };
94
95 assert!(rule.validate(&message).is_none());
96 }
97
98 #[test]
99 fn test_short_body() {
100 let rule = BodyMaxLength {
101 length: 10, ..Default::default()
103 };
104 let message = Message {
105 body: Some("Hello, I'm a long body".to_string()),
106 description: None,
107 footers: None,
108 r#type: Some("feat".to_string()),
109 raw: "feat(scope): broadcast $destroy event on scope destruction
110
111Hello, I'm a long body"
112 .to_string(),
113 scope: Some("scope".to_string()),
114 subject: None,
115 };
116
117 let violation = rule.validate(&message);
118 assert!(violation.is_some());
119 assert_eq!(violation.clone().unwrap().level, Level::Error);
120 assert_eq!(
121 violation.unwrap().message,
122 format!("body is longer than {} characters", rule.length)
123 );
124 }
125}