use crate::api;
use crate::arguments::Entity;
use crate::models;
use api::client::ApiClient;
use colored::Colorize;
use models::ResultWithDefaultError;
use std::io::{self, BufWriter, Write};
pub struct ListCommand;
impl ListCommand {
pub async fn execute(
api_client: impl ApiClient,
count: Option<usize>,
json_flag: bool,
since: Option<String>,
until: Option<String>,
entity: Option<Entity>,
) -> ResultWithDefaultError<()> {
if let Some(Entity::Tag { json: entity_json }) = entity {
let json = json_flag || entity_json;
let user = api_client.get_user().await?;
match api_client.get_tags(user.default_workspace_id).await {
Err(error) => println!("{}\n{}", "Couldn't fetch tags from API".red(), error),
Ok(tags) => {
let stdout = io::stdout();
let mut handle = BufWriter::new(stdout);
let tags = tags
.iter()
.take(count.unwrap_or(usize::MAX))
.collect::<Vec<_>>();
if json {
let json_string = serde_json::to_string_pretty(&tags)
.expect("failed to serialize tags to JSON");
writeln!(handle, "{json_string}").expect("failed to print");
} else {
tags.iter()
.for_each(|tag| writeln!(handle, "{tag}").expect("failed to print"));
}
}
}
return Ok(());
}
let is_time_entry = matches!(entity, None | Some(Entity::TimeEntry { .. }));
let has_date_filter = since.is_some() || until.is_some();
if is_time_entry && has_date_filter {
let stdout = io::stdout();
let mut handle = BufWriter::new(stdout);
let json = match &entity {
Some(Entity::TimeEntry { json }) => json_flag || *json,
_ => json_flag,
};
match api_client.get_time_entries_filtered(since, until).await {
Err(error) => println!(
"{}\n{}",
"Couldn't fetch time entries from API".red(),
error
),
Ok(entries) => {
let entries = entries
.iter()
.take(count.unwrap_or(usize::MAX))
.collect::<Vec<_>>();
if json {
let json_string = serde_json::to_string_pretty(&entries)
.expect("failed to serialize time entries to JSON");
writeln!(handle, "{json_string}").expect("failed to print");
} else {
entries
.iter()
.for_each(|te| writeln!(handle, "{te}").expect("failed to print"));
}
}
}
return Ok(());
}
match api_client.get_entities().await {
Err(error) => println!(
"{}\n{}",
"Couldn't fetch time entries the from API".red(),
error
),
Ok(entities) => {
let stdout = io::stdout();
let mut handle = BufWriter::new(stdout);
match entity.unwrap_or(Entity::TimeEntry { json: false }) {
Entity::TimeEntry { json: entity_json } => {
let json = json_flag || entity_json;
let entries = entities
.time_entries
.iter()
.take(count.unwrap_or(usize::MAX))
.collect::<Vec<_>>();
if json {
let json_string = serde_json::to_string_pretty(&entries)
.expect("failed to serialize time entries to JSON");
writeln!(handle, "{json_string}").expect("failed to print");
} else {
entries.iter().for_each(|time_entry| {
writeln!(handle, "{time_entry}").expect("failed to print")
});
}
}
Entity::Project { json: entity_json } => {
let json = json_flag || entity_json;
let projects = entities
.projects
.values()
.take(count.unwrap_or(usize::MAX))
.collect::<Vec<_>>();
if json {
let json_string = serde_json::to_string_pretty(&projects)
.expect("failed to serialize projects to JSON");
writeln!(handle, "{json_string}").expect("failed to print");
} else {
projects.iter().for_each(|project| {
writeln!(handle, "{project}").expect("failed to print")
});
}
}
Entity::Tag { .. } => unreachable!(),
};
}
}
Ok(())
}
}