1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
mod client; mod conf; mod opts; use anyhow::{anyhow, Result}; use client::YoutrackService; pub use conf::Configuration; pub use opts::Opts; use term_grid::{Cell, Direction, Filling, Grid, GridOptions}; #[derive(Debug)] pub struct Command { pub issue_id: String, pub query: String, pub comment: Option<String>, } type ParsedCommand = String; pub trait CommandService { fn execute_command(&self, command: Command) -> Result<Vec<ParsedCommand>>; } #[derive(Debug)] pub struct ListedIssue { pub id: String, pub summary: String, } pub trait ListingService { fn list_issues(&self, query: String, limit: Option<u8>, offset: u8) -> Result<Vec<ListedIssue>>; } pub fn run(opts: Opts, conf: Configuration) -> Result<()> { let youtrack_service = YoutrackService::new(&conf.youtrack_url, &conf.auth_token); match opts { Opts::Issue { issue_id, command, comment, } => { let command = Command { issue_id, query: command, comment, }; let executed_commands = youtrack_service.execute_command(command)?; println!("Executed commands:"); executed_commands .iter() .for_each(|command| println!(" {}", command)); Ok(()) } Opts::List { query, limit, offset, } => { let issues = youtrack_service.list_issues(query, limit, offset.unwrap_or(0))?; let mut grid = Grid::new(GridOptions { filling: Filling::Spaces(2), direction: Direction::LeftToRight, }); for issue in issues { grid.add(Cell::from(issue.id)); grid.add(Cell::from(issue.summary)); } print!("{}", grid.fit_into_columns(2)); Ok(()) } Opts::Console => Err(anyhow!("Console mode not implemented")), } }