Specific areas in which I'd love to get feedback:
- Is it good to have the
Command
struct own theString
s (description
field)? Or since these strings aren't really meant to change, should I rather have them as&'static str
s?- I initially used
String
but then switched to&'static str
, and then I saw this SO post and switched back toString
.
- I initially used
- Within the
print_table
function, am I complicating the code by having themax_lengths
(for two fields of theCommand
struct) as a tuple instead of using two separate scalar variables? - Also, is there a more idiomatic way of finding the maximum of lengths of a
String
field in array of structs? - I've seen imports being placed at the top (e.g.,
use std::cmp::max
) before the functions are used (max(1, 2)
). I know that this keeps the code terse. However, I'm also a fan of qualified naming (e.g., in Python, it's encouraged to doimport math; math.pow(x, y)
instead offrom math import pow; pow(x, y)
). This way, to readers, there's no confusion about the source of a function. What's the general consensus of Rust community? Up to each dev?
fn main() {
let commands: [Command; 3] = [
Command {code: '1', description: String::from("Start your instance")},
Command {code: '2', description: String::from("Stop your instance")},
Command {code: 'q', description: String::from("Quit")},
];
print_table(&commands);
for cmd in commands.iter() {
match cmd.code {
'1' => println!("Starting instance"),
'2' => println!("Stopping instance"),
'q' => println!("Quitting"),
_ => println!("Invalid option"),
}
}
}
fn print_table(commands: &[Command; 3]) {
const BUFFER: usize = 2;
const HEADING: (&str, &str) = ("Code", "Description");
const VERTICAL_BAR: &str = "│";
const HORIZONTAL_SEP: &str = "─";
std::process::Command::new("clear").status().unwrap();
let mut max_lengths: (usize, usize) = (0, 0);
for cmd in commands.iter() {
max_lengths.0 = std::cmp::max(max_lengths.0, cmd.code.len_utf8());
max_lengths.1 = std::cmp::max(max_lengths.1, cmd.description.len());
}
max_lengths.0 = std::cmp::max(max_lengths.0, HEADING.0.len());
max_lengths.1 = std::cmp::max(max_lengths.1, HEADING.1.len());
let horizontal_lines: (&str, &str) = (
&HORIZONTAL_SEP.repeat(max_lengths.0 + BUFFER),
&HORIZONTAL_SEP.repeat(max_lengths.1 + BUFFER),
);
println!("╭{}┬{}╮", horizontal_lines.0, horizontal_lines.1);
println!("{VERTICAL_BAR}{:^w1$}{VERTICAL_BAR} {:^w2$}{VERTICAL_BAR}", HEADING.0, HEADING.1, w1=max_lengths.0+BUFFER, w2=max_lengths.1+BUFFER-1);
println!("├{}┼{}┤", horizontal_lines.0, horizontal_lines.1);
for cmd in commands.iter() {
println!("{VERTICAL_BAR}{:^w1$}{VERTICAL_BAR} {:<w2$}{VERTICAL_BAR}", cmd.code, cmd.description, w1=max_lengths.0+BUFFER, w2=max_lengths.1+BUFFER-1);
}
println!("╰{}┴{}╯", horizontal_lines.0, horizontal_lines.1);
}
struct Command {
code: char,
description: String,
}