stern4rust/finding/model/
test_marker.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum MarkerPhase {
9 Arrange,
10 Act,
11 Assert,
12}
13
14pub struct TestMarker {
27 pub line: usize,
28 pub label: String,
29 pub phases: Vec<MarkerPhase>,
30}
31
32impl TestMarker {
33 pub const FORMS: [&'static str; 6] = [
35 "Arrange & Act & Assert",
36 "Arrange & Act",
37 "Act & Assert",
38 "Arrange",
39 "Assert",
40 "Act",
41 ];
42
43 pub fn parse(text: &str, line: usize) -> Option<Self> {
44 let comment = text.trim_start().strip_prefix("//")?.trim_start();
45 let form = Self::form_of(comment)?;
46 Some(Self {
47 line,
48 label: format!("// {form}"),
49 phases: Self::phases_of(form),
50 })
51 }
52
53 fn form_of(comment: &str) -> Option<&'static str> {
54 Self::FORMS
55 .into_iter()
56 .find(|form| Self::is_form(comment, form))
57 }
58
59 fn is_form(comment: &str, form: &str) -> bool {
61 comment.strip_prefix(form).is_some_and(|rest| {
62 rest.chars()
63 .next()
64 .is_none_or(|next| !next.is_alphanumeric() && next != '_')
65 })
66 }
67
68 fn phases_of(form: &str) -> Vec<MarkerPhase> {
69 match form {
70 "Arrange & Act & Assert" => {
71 vec![MarkerPhase::Arrange, MarkerPhase::Act, MarkerPhase::Assert]
72 }
73 "Arrange & Act" => vec![MarkerPhase::Arrange, MarkerPhase::Act],
74 "Act & Assert" => vec![MarkerPhase::Act, MarkerPhase::Assert],
75 "Arrange" => vec![MarkerPhase::Arrange],
76 "Assert" => vec![MarkerPhase::Assert],
77 _ => vec![MarkerPhase::Act],
78 }
79 }
80}