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("Permission is hereby granted, free of charge, to any person obtaining a copy\n");
69 output.push_str("of this software and associated documentation files (the \"Software\"), to deal\n");
70 output.push_str("in the Software without restriction, including without limitation the rights\n");
71 output.push_str("to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n");
72 output.push_str("copies of the Software, and to permit persons to whom the Software is\n");
73 output.push_str("furnished to do so, subject to the following conditions:\n");
74 output.push('\n');
75 output.push_str("The above copyright notice and this permission notice shall be included in all\n");
76 output.push_str("copies or substantial portions of the Software.\n");
77 output.push('\n');
78 output.push_str("THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n");
79 output.push_str("IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n");
80 output.push_str("FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n");
81 output.push_str("AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n");
82 output.push_str("LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n");
83 output.push_str("OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n");
84 output.push_str("SOFTWARE.\n");
85 }
86 LicenseType::Apache2 => {
87 output.push_str("Apache License 2.0 - A permissive license that allows:\n");
88 output.push_str("• Commercial use\n");
89 output.push_str("• Modification\n");
90 output.push_str("• Distribution\n");
91 output.push_str("• Patent use\n");
92 output.push_str("• Private use\n");
93 output.push('\n');
94 output.push_str("Requires:\n");
95 output.push_str("• License and copyright notice\n");
96 output.push_str("• State changes\n");
97 }
98 LicenseType::CC0 => {
99 output.push_str("Creative Commons CC0 1.0 Universal - Public domain dedication:\n");
100 output.push_str("• No rights reserved\n");
101 output.push_str("• Can be used for any purpose\n");
102 output.push_str("• No attribution required\n");
103 }
104 }
105
106 output.push('\n');
107
108 if output::is_tty() {
109 use colored::Colorize;
110 use std::fmt::Write;
111 writeln!(output, "For full license text, see: {}", "LICENSE file in project root".blue().underline()).unwrap();
112 } else {
113 output.push_str("For full license text, see: LICENSE file in project root\n");
114 }
115
116 output
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_license_type_from_str() {
125 assert_eq!(LicenseType::parse("MIT"), Some(LicenseType::MIT));
126 assert_eq!(LicenseType::parse("mit"), Some(LicenseType::MIT));
127 assert_eq!(LicenseType::parse("Apache-2.0"), Some(LicenseType::Apache2));
128 assert_eq!(LicenseType::parse("apache"), Some(LicenseType::Apache2));
129 assert_eq!(LicenseType::parse("CC0-1.0"), Some(LicenseType::CC0));
130 assert_eq!(LicenseType::parse("cc0"), Some(LicenseType::CC0));
131 assert_eq!(LicenseType::parse("unknown"), None);
132 }
133
134 #[test]
135 fn test_license_type_name() {
136 assert_eq!(LicenseType::MIT.name(), "MIT");
137 assert_eq!(LicenseType::Apache2.name(), "Apache-2.0");
138 assert_eq!(LicenseType::CC0.name(), "CC0-1.0");
139 }
140
141 #[test]
142 fn test_display_license_mit() {
143 let output = display_license("test-tool", LicenseType::MIT);
144 assert!(output.contains("test-tool"));
145 assert!(output.contains("MIT"));
146 assert!(output.contains("Permission is hereby granted"));
147 assert!(output.contains("Commercial use"));
148 }
149
150 #[test]
151 fn test_display_license_apache() {
152 let output = display_license("test-tool", LicenseType::Apache2);
153 assert!(output.contains("test-tool"));
154 assert!(output.contains("Apache"));
155 assert!(output.contains("Patent use"));
156 }
157
158 #[test]
159 fn test_display_license_cc0() {
160 let output = display_license("test-tool", LicenseType::CC0);
161 assert!(output.contains("test-tool"));
162 assert!(output.contains("CC0"));
163 assert!(output.contains("No rights reserved"));
164 }
165}