workhelix_cli_common/
license.rs1use crate::output;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum LicenseType {
10 MIT,
12 Apache2,
14 CC0,
16}
17
18impl LicenseType {
19 #[must_use]
23 pub fn parse(s: &str) -> Option<Self> {
24 match s.to_uppercase().as_str() {
25 "MIT" => Some(Self::MIT),
26 "APACHE-2.0" | "APACHE2" | "APACHE" => Some(Self::Apache2),
27 "CC0-1.0" | "CC0" => Some(Self::CC0),
28 _ => None,
29 }
30 }
31
32 #[must_use]
34 pub const fn name(self) -> &'static str {
35 match self {
36 Self::MIT => "MIT",
37 Self::Apache2 => "Apache-2.0",
38 Self::CC0 => "CC0-1.0",
39 }
40 }
41}
42
43#[must_use]
52pub fn display_license(tool_name: &str, license: LicenseType) -> String {
53 let mut output = format!("{tool_name} is licensed under {}\n\n", license.name());
54
55 match license {
56 LicenseType::MIT => {
57 output.push_str("MIT License - A permissive license that allows:\n");
58 output.push_str("• Commercial use\n");
59 output.push_str("• Modification\n");
60 output.push_str("• Distribution\n");
61 output.push_str("• Private use\n");
62 output.push('\n');
63 output.push_str("Requires:\n");
64 output.push_str("• License and copyright notice\n");
65 output.push('\n');
66 output.push_str("MIT License\n");
67 output.push('\n');
68 output.push_str(
69 "Permission is hereby granted, free of charge, to any person obtaining a copy\n",
70 );
71 output.push_str(
72 "of this software and associated documentation files (the \"Software\"), to deal\n",
73 );
74 output.push_str(
75 "in the Software without restriction, including without limitation the rights\n",
76 );
77 output.push_str(
78 "to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n",
79 );
80 output.push_str(
81 "copies of the Software, and to permit persons to whom the Software is\n",
82 );
83 output.push_str("furnished to do so, subject to the following conditions:\n");
84 output.push('\n');
85 output.push_str(
86 "The above copyright notice and this permission notice shall be included in all\n",
87 );
88 output.push_str("copies or substantial portions of the Software.\n");
89 output.push('\n');
90 output.push_str(
91 "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
92 );
93 output.push_str(
94 "IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
95 );
96 output.push_str(
97 "FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n",
98 );
99 output.push_str(
100 "AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
101 );
102 output.push_str(
103 "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n",
104 );
105 output.push_str(
106 "OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n",
107 );
108 output.push_str("SOFTWARE.\n");
109 }
110 LicenseType::Apache2 => {
111 output.push_str("Apache License 2.0 - A permissive license that allows:\n");
112 output.push_str("• Commercial use\n");
113 output.push_str("• Modification\n");
114 output.push_str("• Distribution\n");
115 output.push_str("• Patent use\n");
116 output.push_str("• Private use\n");
117 output.push('\n');
118 output.push_str("Requires:\n");
119 output.push_str("• License and copyright notice\n");
120 output.push_str("• State changes\n");
121 }
122 LicenseType::CC0 => {
123 output.push_str("Creative Commons CC0 1.0 Universal - Public domain dedication:\n");
124 output.push_str("• No rights reserved\n");
125 output.push_str("• Can be used for any purpose\n");
126 output.push_str("• No attribution required\n");
127 }
128 }
129
130 output.push('\n');
131
132 if output::is_tty() {
133 use colored::Colorize;
134 use std::fmt::Write;
135 writeln!(
136 output,
137 "For full license text, see: {}",
138 "LICENSE file in project root".blue().underline()
139 )
140 .unwrap();
141 } else {
142 output.push_str("For full license text, see: LICENSE file in project root\n");
143 }
144
145 output
146}
147
148#[cfg(test)]
149mod tests {
150 use super::*;
151
152 #[test]
153 fn test_license_type_from_str() {
154 assert_eq!(LicenseType::parse("MIT"), Some(LicenseType::MIT));
155 assert_eq!(LicenseType::parse("mit"), Some(LicenseType::MIT));
156 assert_eq!(LicenseType::parse("Apache-2.0"), Some(LicenseType::Apache2));
157 assert_eq!(LicenseType::parse("apache"), Some(LicenseType::Apache2));
158 assert_eq!(LicenseType::parse("CC0-1.0"), Some(LicenseType::CC0));
159 assert_eq!(LicenseType::parse("cc0"), Some(LicenseType::CC0));
160 assert_eq!(LicenseType::parse("unknown"), None);
161 }
162
163 #[test]
164 fn test_license_type_name() {
165 assert_eq!(LicenseType::MIT.name(), "MIT");
166 assert_eq!(LicenseType::Apache2.name(), "Apache-2.0");
167 assert_eq!(LicenseType::CC0.name(), "CC0-1.0");
168 }
169
170 #[test]
171 fn test_display_license_mit() {
172 let output = display_license("test-tool", LicenseType::MIT);
173 assert!(output.contains("test-tool"));
174 assert!(output.contains("MIT"));
175 assert!(output.contains("Permission is hereby granted"));
176 assert!(output.contains("Commercial use"));
177 }
178
179 #[test]
180 fn test_display_license_apache() {
181 let output = display_license("test-tool", LicenseType::Apache2);
182 assert!(output.contains("test-tool"));
183 assert!(output.contains("Apache"));
184 assert!(output.contains("Patent use"));
185 }
186
187 #[test]
188 fn test_display_license_cc0() {
189 let output = display_license("test-tool", LicenseType::CC0);
190 assert!(output.contains("test-tool"));
191 assert!(output.contains("CC0"));
192 assert!(output.contains("No rights reserved"));
193 }
194}