Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add description to dscresource struct and tablewriter for list #117

Merged
merged 2 commits into from
Aug 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions dsc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@ use syntect::easy::HighlightLines;
use syntect::parsing::SyntaxSet;
use syntect::highlighting::{ThemeSet, Style};
use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings};
use tablewriter::Table;

#[cfg(debug_assertions)]
use crossterm::event;
#[cfg(debug_assertions)]
use std::env;

pub mod args;
pub mod tablewriter;

const EXIT_SUCCESS: i32 = 0;
const EXIT_INVALID_ARGS: i32 = 1;
Expand Down Expand Up @@ -348,21 +350,41 @@ fn handle_resource_subcommand(subcommand: &ResourceSubCommand, format: &Option<O
exit(EXIT_DSC_ERROR);
}
};
let mut write_table = false;
let mut table = Table::new(vec!["Type", "Version", "Requires", "Description"]);
if format.is_none() && atty::is(Stream::Stdout) {
// write as table if fornat is not specified and interactive
write_table = true;
}
for resource in dsc.find_resource(&resource_name.clone().unwrap_or_default()) {
// convert to json
let json = match serde_json::to_string(&resource) {
Ok(json) => json,
Err(err) => {
eprintln!("JSON Error: {err}");
exit(EXIT_JSON_ERROR);
if write_table {
table.add_row(vec![
resource.type_name,
resource.version,
resource.requires.unwrap_or_default(),
resource.description.unwrap_or_default()
]);
}
else {
// convert to json
let json = match serde_json::to_string(&resource) {
Ok(json) => json,
Err(err) => {
eprintln!("JSON Error: {err}");
exit(EXIT_JSON_ERROR);
}
};
write_output(&json, format);
// insert newline separating instances if writing to console
if atty::is(Stream::Stdout) {
println!();
}
};
write_output(&json, format);
// insert newline separating instances if writing to console
if atty::is(Stream::Stdout) {
println!();
}
}

if write_table {
table.print();
}
},
ResourceSubCommand::Get { resource, input } => {
handle_resource_get(&mut dsc, resource, input, stdin, format);
Expand Down
74 changes: 74 additions & 0 deletions dsc/src/tablewriter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crossterm::terminal::{size};

pub struct Table {
header: Vec<String>,
rows: Vec<Vec<String>>,
column_widths: Vec<usize>,
}

impl Table {
pub fn new(header: Vec<&str>) -> Table {
let mut column_widths = Vec::new();
for header_text in header.iter() {
column_widths.push(header_text.len());
}
let header = header.iter().map(|s| s.to_string()).collect::<Vec<String>>();
Table {
header,
rows: Vec::new(),
column_widths,
}
}

pub fn add_row(&mut self, row: Vec<String>) {
for (i, column) in row.iter().enumerate() {
if column.len() > self.column_widths[i] {
self.column_widths[i] = column.len();
}
}
self.rows.push(row);
}

pub fn print(&self) {
let (width, _) = size().unwrap();
// make header bright green
println!("\x1b[1;32m");
let mut header_row = String::new();
let last_column = self.header.len() - 1;
for (i, column) in self.header.iter().enumerate() {
header_row.push_str(&format!("{:<width$}", column, width = self.column_widths[i]));
if i != last_column {
header_row.push_str(" ");
}
}
// if header row is too wide, truncate
if header_row.len() > width as usize {
header_row.truncate(width as usize);
}

println!("{header_row}");
println!("{}\x1b[0m", "-".repeat(header_row.len()));

// TODO: make this smarter by splitting long text to multiple lines
for row in &self.rows {
let mut row_str = String::new();
for (i, column) in row.iter().enumerate() {
row_str.push_str(&format!("{:<width$}", column, width = self.column_widths[i]));
if i != last_column {
row_str.push_str(" ");
}
}

// if row is too wide and last character is not a space, truncate and add ellipsis unicode character
if row_str.len() > width as usize {
row_str.truncate(width as usize);
if !row_str.ends_with(' ') {
row_str.pop();
row_str.push('…');
}
}

println!("{row_str}");
}
}
}
2 changes: 2 additions & 0 deletions dsc_lib/src/discovery/command_discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ fn import_manifest(path: &Path) -> Result<DscResource, DscError> {
let resource = DscResource {
type_name: manifest.resource_type.clone(),
implemented_as: ImplementedAs::Command,
description: manifest.description.clone(),
version: manifest.version.clone(),
path: path.to_str().unwrap().to_string(),
directory: path.parent().unwrap().to_str().unwrap().to_string(),
manifest: Some(serde_json::to_value(manifest)?),
Expand Down
3 changes: 3 additions & 0 deletions dsc_lib/src/dscresources/dscresource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub struct DscResource {
pub version: String,
/// The file path to the resource.
pub path: String,
/// The description of the resource.
pub description: Option<String>,
// The directory path to the resource.
pub directory: String,
/// The implementation of the resource.
Expand Down Expand Up @@ -48,6 +50,7 @@ impl DscResource {
Self {
type_name: String::new(),
version: String::new(),
description: None,
path: String::new(),
directory: String::new(),
implemented_as: ImplementedAs::Command,
Expand Down
3 changes: 3 additions & 0 deletions test_group_resource/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ fn main() {
let resource1 = DscResource {
type_name: "TestResource1".to_string(),
version: "1.0.0".to_string(),
description: Some("This is a test resource.".to_string()),
implemented_as: ImplementedAs::Custom("TestResource".to_string()),
path: "test_resource1".to_string(),
directory: "test_directory".to_string(),
Expand All @@ -29,6 +30,7 @@ fn main() {
let resource2 = DscResource {
type_name: "TestResource2".to_string(),
version: "1.0.1".to_string(),
description: Some("This is a test resource.".to_string()),
implemented_as: ImplementedAs::Custom("TestResource".to_string()),
path: "test_resource2".to_string(),
directory: "test_directory".to_string(),
Expand All @@ -46,6 +48,7 @@ fn main() {
let resource1 = DscResource {
type_name: "InvalidResource".to_string(),
version: "1.0.0".to_string(),
description: Some("This is a test resource.".to_string()),
implemented_as: ImplementedAs::Custom("TestResource".to_string()),
path: "test_resource1".to_string(),
directory: "test_directory".to_string(),
Expand Down