Skip to content

Commit

Permalink
add output format configuration
Browse files Browse the repository at this point in the history
Add functionality to output application information in pretty formatting
(human-readable) or plain json for integrating application output with
other tools.
  • Loading branch information
keinsell committed Dec 31, 2024
1 parent d5e8bdd commit 74c58d5
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 11 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ clap_autocomplete = "0.4.2"
tantivy = "0.22.0"
clap_complete = "4.5.40"
clap_complete_command = "0.6.1"
atty = "0.2.14"
[dependencies.sea-orm-migration]
version = "1.1.0"
features = [
Expand All @@ -59,6 +60,7 @@ async-stream = { version = "0.3" }
futures-util = { version = "0.3" }
clap = { version = "4" }
directories = { version = "5.0.0" }
atty = "0.2"

[profile.dist]
inherits = "release"
Expand Down
5 changes: 2 additions & 3 deletions src/command/get_substance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,14 @@ mod tests
use crate::lib::migrate_database;
use crate::lib::Context;
use crate::lib::DATABASE_CONNECTION;
use crate::OutputFormat;

#[async_std::test]
async fn should_return_caffeine()
{
migrate_database(&DATABASE_CONNECTION).await.unwrap();

let context = Context {
database_connection: &DATABASE_CONNECTION,
};
let context = Context {database_connection: &DATABASE_CONNECTION, output_format: OutputFormat::Pretty };


let command = GetSubstance {
Expand Down
11 changes: 6 additions & 5 deletions src/ingestion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::lib::parse_date_string;
use crate::lib::route_of_administration::RouteOfAdministrationClassification;
use crate::lib::CommandHandler;
use crate::lib::Context;
use crate::lib::output::{Formattable, FormattableVec};
use crate::orm::ingestion;
use crate::orm::prelude::Ingestion;
use async_std::task::block_on;
Expand Down Expand Up @@ -40,6 +41,8 @@ pub struct ViewModel
pub ingested_at: String,
}

impl Formattable for ViewModel {}

impl From<ingestion::Model> for ViewModel
{
fn from(model: ingestion::Model) -> Self
Expand Down Expand Up @@ -182,11 +185,9 @@ impl CommandHandler for ListIngestion
return Ok(());
}

let table = Table::new(ingestions.iter().map(|i| ViewModel::from(i.clone())))
.with(tabled::settings::Style::modern())
.to_string();

println!("{}", table);
let view_models: Vec<ViewModel> = ingestions.iter().map(|i| ViewModel::from(i.clone())).collect();
let formatted = FormattableVec::new(view_models).format(context.output_format);
println!("{}", formatted);

Ok(())
}
Expand Down
8 changes: 5 additions & 3 deletions src/lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ use sea_orm_migration::MigratorTrait;
use std::env::temp_dir;
use std::fmt::Debug;
use std::path::PathBuf;
use crate::OutputFormat;

pub mod dosage;
pub mod route_of_administration;
pub mod output;

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub struct Context<'a>
{
pub(crate) database_connection: &'a DatabaseConnection,
pub database_connection: &'a sea_orm::DatabaseConnection,
pub output_format: OutputFormat,
}

#[async_trait]
Expand Down Expand Up @@ -67,7 +70,6 @@ lazy_static::lazy_static! {

// Try to open database connection
debug!("Opening database connection to {}", sqlite_path);
println!("Connecting into {}", sqlite_path);

match block_on(async { Database::connect(&sqlite_path).await }) {
Ok(connection) => {
Expand Down
43 changes: 43 additions & 0 deletions src/lib/output.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use serde::Serialize;
use tabled::Table;
use tabled::Tabled;
use crate::OutputFormat;

pub trait Formattable: Serialize + Tabled + Sized {
fn format(&self, format: OutputFormat) -> String {
match format {
OutputFormat::Pretty => {
Table::new(std::iter::once(self))
.with(tabled::settings::Style::modern())
.to_string()
}
OutputFormat::Json => {
serde_json::to_string_pretty(self).unwrap_or_else(|_| "Error serializing to JSON".to_string())
}
}
}
}

pub struct FormattableVec<T: Formattable>(Vec<T>);

impl<T: Formattable> FormattableVec<T> {
pub fn new(items: Vec<T>) -> Self {
Self(items)
}

pub fn format(&self, format: OutputFormat) -> String {
match format {
OutputFormat::Pretty => {
if self.0.is_empty() {
return "No items found.".to_string();
}
Table::new(&self.0)
.with(tabled::settings::Style::modern())
.to_string()
}
OutputFormat::Json => {
serde_json::to_string_pretty(&self.0).unwrap_or_else(|_| "Error serializing to JSON".to_string())
}
}
}
}
23 changes: 23 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use lib::DATABASE_CONNECTION;
use rust_embed::Embed;
use sea_orm::prelude::async_trait::async_trait;
use std::string::ToString;
use atty::Stream;

mod command;
mod db;
Expand All @@ -37,6 +38,14 @@ lazy_static! {
static ref FIGURE: figlet_rs::FIGure<'static> = FIGFONT.convert("psylog").unwrap();
}

fn default_output_format() -> OutputFormat {
if atty::is(Stream::Stdout) {
OutputFormat::Pretty
} else {
OutputFormat::Json
}
}

#[derive(Parser)]
#[command(
version = env!("CARGO_PKG_VERSION"),
Expand All @@ -47,10 +56,23 @@ pub struct CLI
{
#[command(subcommand)]
pub command: ApplicationCommands,

/// Output format for the command results
#[arg(short = 'o', long = "output", value_enum, default_value_t = default_output_format())]
pub output_format: OutputFormat,

#[command(flatten)]
verbose: clap_verbosity_flag::Verbosity,
}

#[derive(clap::ValueEnum, Clone, Debug)]
pub enum OutputFormat {
/// Pretty printed tables
Pretty,
/// JSON formatted output
Json,
}

fn default_complete_shell() -> clap_complete::Shell
{
clap_complete::shells::Shell::from_env().unwrap()
Expand Down Expand Up @@ -122,6 +144,7 @@ async fn main()

let context = Context {
database_connection: &DATABASE_CONNECTION,
output_format: cli.output_format,
};

migrate_database(context.database_connection)
Expand Down
3 changes: 3 additions & 0 deletions src/substance.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::lib::CommandHandler;
use crate::lib::Context;
use crate::lib::output::{Formattable, FormattableVec};
use clap::Parser;
use clap::Subcommand;
use sea_orm::prelude::async_trait::async_trait;
Expand All @@ -19,6 +20,8 @@ pub struct ViewModel
pub common_names: String,
}

impl Formattable for ViewModel {}

impl From<SubstanceTable> for ViewModel
{
fn from(model: SubstanceTable) -> Self
Expand Down

0 comments on commit 74c58d5

Please sign in to comment.