1use crate::env;
4use chrono::Local;
5use std::io::Write;
6use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
7
8#[derive(Default)]
9pub struct MotdOptions<'a> {
10 pub mode: Option<&'a str>, pub timestamp: Option<&'a str>, pub environment: Option<&'a str>, pub copyright: Option<&'a [&'a str]>,
14}
15
16pub fn capitalize_first(s: &str) -> String {
18 let lower = s.to_lowercase();
19 let mut c = lower.chars();
20 match c.next() {
21 None => String::new(),
22 Some(f) => f.to_uppercase().collect::<String>() + c.as_str(),
23 }
24}
25
26pub fn print_motd(pkg_name: &str, build_info: &str, opts: MotdOptions) -> std::io::Result<()> {
27 let mut stdout = StandardStream::stdout(ColorChoice::Auto);
28 let pkg_version = env!("CARGO_PKG_VERSION");
29
30 writeln!(&mut stdout)?;
31 stdout.set_color(ColorSpec::new().set_fg(Some(Color::Magenta)))?;
32 write!(&mut stdout, " ▲ {} {}", pkg_name, pkg_version)?;
33 stdout.reset()?;
34
35 if !build_info.is_empty() && build_info != "None" {
36 if build_info.starts_with("(") {
37 write!(&mut stdout, " {}", build_info)?;
38 } else {
39 write!(&mut stdout, " ({})", build_info)?;
40 }
41 }
42 writeln!(&mut stdout)?;
43
44 if opts.timestamp.unwrap_or("") != "None" {
46 let ts = Local::now().format("%Y-%m-%d %H:%M:%S");
47 writeln!(&mut stdout, " - Timestamp: {}", ts)?;
48 }
49
50 if let Some(lines) = opts.copyright {
52 if !lines.is_empty() {
53 writeln!(&mut stdout, " - Copyright:")?;
54 for l in lines {
55 writeln!(&mut stdout, " ✓ {}", l)?;
56 }
57 }
58 }
59
60 if opts.environment.unwrap_or("") != "None" {
62 writeln!(&mut stdout, " - Environment:")?;
63 env::print_environment(&mut stdout, opts.mode.unwrap_or(""))?;
64 }
65
66 writeln!(&mut stdout)?;
67 Ok(())
68}