1use uuid::Uuid;
5
6use super::LifecycleState;
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
10pub enum FilesHint {
11 Upload,
13 CheckOut,
15 LockedByOther,
17 InReview,
19 Frozen { can_revise: bool },
21 Hidden,
23}
24
25impl FilesHint {
26 pub fn as_str(self) -> &'static str {
28 match self {
29 FilesHint::Upload => "upload",
30 FilesHint::CheckOut => "checkout",
31 FilesHint::LockedByOther => "locked",
32 FilesHint::InReview => "review",
33 FilesHint::Frozen { .. } => "frozen",
34 FilesHint::Hidden => "hidden",
35 }
36 }
37}
38
39pub fn files_hint(
43 state: LifecycleState,
44 locked_by: Option<Uuid>,
45 me: Uuid,
46 editable: bool,
47 can_work: bool,
48 can_revise: bool,
49) -> FilesHint {
50 if editable {
51 return FilesHint::Upload;
52 }
53 match state {
54 LifecycleState::InWork => match locked_by {
55 Some(owner) if owner != me => FilesHint::LockedByOther,
56 Some(_) => FilesHint::Hidden,
57 None if can_work => FilesHint::CheckOut,
58 None => FilesHint::Hidden,
59 },
60 LifecycleState::InReview => FilesHint::InReview,
61 LifecycleState::Released | LifecycleState::Obsolete => FilesHint::Frozen { can_revise },
62 }
63}
64
65pub fn files_type_hint(item_type: &str) -> Option<&'static str> {
67 match item_type {
68 "simulation" => Some(
69 "Solver input, models, result files and reports. Large result files are stored, not parsed.",
70 ),
71 "part" => Some("The CAD model, the drawing and a STEP export (for the 3D preview)."),
72 _ => None,
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use LifecycleState::*;
80
81 #[test]
82 fn each_state_has_its_hint() {
83 let me = Uuid::new_v4();
84 let other = Uuid::new_v4();
85 let h = |s, l, e, w, r| files_hint(s, l, me, e, w, r);
86 assert_eq!(h(InWork, Some(me), true, true, false), FilesHint::Upload);
87 assert_eq!(h(InWork, None, false, true, false), FilesHint::CheckOut);
88 assert_eq!(
89 h(InWork, Some(other), false, false, false),
90 FilesHint::LockedByOther
91 );
92 assert_eq!(h(InReview, None, false, false, false), FilesHint::InReview);
93 assert_eq!(
94 h(Released, None, false, false, true),
95 FilesHint::Frozen { can_revise: true }
96 );
97 assert_eq!(
98 h(Obsolete, None, false, false, false),
99 FilesHint::Frozen { can_revise: false }
100 );
101 }
102
103 #[test]
104 fn viewers_and_outsiders_get_no_add_path() {
105 let me = Uuid::new_v4();
106 assert_eq!(
107 files_hint(InWork, None, me, false, false, false),
108 FilesHint::Hidden
109 );
110 assert_eq!(
111 files_hint(InWork, Some(me), me, false, false, false),
112 FilesHint::Hidden
113 );
114 }
115
116 #[test]
117 fn type_hints() {
118 assert!(files_type_hint("simulation").unwrap().contains("result"));
119 assert!(files_type_hint("part").unwrap().contains("STEP"));
120 assert!(files_type_hint("document").is_none());
121 }
122
123 #[test]
125 fn kinds_are_the_names_the_template_uses() {
126 let kinds = [
127 (FilesHint::Upload, "upload"),
128 (FilesHint::CheckOut, "checkout"),
129 (FilesHint::LockedByOther, "locked"),
130 (FilesHint::InReview, "review"),
131 (FilesHint::Frozen { can_revise: true }, "frozen"),
132 (FilesHint::Frozen { can_revise: false }, "frozen"),
133 (FilesHint::Hidden, "hidden"),
134 ];
135 let template = include_str!("../../templates/revisions/show.html");
136 for (hint, name) in kinds {
137 assert_eq!(hint.as_str(), name);
138 if hint != FilesHint::Hidden {
139 assert!(
140 template.contains(&format!("fh.kind == \"{name}\"")),
141 "the template handles {name}"
142 );
143 }
144 }
145 }
146}