gr_bin/formatters/
formatter.rs

1use super::utils::to_fixed_length;
2use crate::vcs::common::{PullRequest, PullRequestState, Repository};
3use colored::Colorize;
4
5pub enum FormatterType {
6    Json,
7    Normal,
8    Short,
9}
10
11pub trait Formatter {
12    fn show_json(&self) -> String;
13    fn show_normal(&self) -> String;
14    fn show_short(&self) -> String;
15    fn show(&self, formatter_type: FormatterType) -> String {
16        match formatter_type {
17            FormatterType::Json => self.show_json(),
18            FormatterType::Normal => self.show_normal(),
19            FormatterType::Short => self.show_short(),
20        }
21    }
22}
23
24const FULL_SIZE: usize = 80;
25const ID_SIZE: usize = 6;
26const TITLE_SIZE: usize = FULL_SIZE - ID_SIZE - 1;
27const SHORT_BRANCH_SIZE: usize = 20;
28const SHORT_TITLE_SIZE: usize = FULL_SIZE - ID_SIZE - 1 - SHORT_BRANCH_SIZE - 1;
29
30impl Formatter for PullRequest {
31    fn show_json(&self) -> String {
32        serde_json::to_string(&self).unwrap()
33    }
34    fn show_normal(&self) -> String {
35        let title = to_fixed_length(&self.title, TITLE_SIZE, true);
36        let title = match self.state {
37            PullRequestState::Open => title.bold(),
38            PullRequestState::Closed => title.bold().red(),
39            PullRequestState::Merged => title.bold().green(),
40            PullRequestState::Locked => title.bold().magenta(),
41        };
42        let colored_id = format!("#{}", self.id).dimmed();
43        let title_line = format!("{} {:>width$}", title, colored_id, width = ID_SIZE);
44        let details_line = format!(
45            "{} {} {} {} {} {}",
46            "opened by".dimmed(),
47            self.author.username,
48            "on".dimmed(),
49            self.created_at.date(),
50            "updated on".dimmed(),
51            self.updated_at.date(),
52        );
53        let branch_line = format!("{} -> {}", self.source.blue(), self.target.blue());
54        let description = if !self.description.is_empty() {
55            format!("\n{}\n---", self.description)
56        } else {
57            "".to_string()
58        };
59        let url_line = format!("{}", self.url.dimmed());
60
61        format!(
62            "{title_line}
63{details_line}
64{branch_line}
65{description}
66{url_line}
67"
68        )
69    }
70    fn show_short(&self) -> String {
71        let title = to_fixed_length(&self.title, SHORT_TITLE_SIZE, true);
72        let title = match self.state {
73            PullRequestState::Open => title.bold(),
74            PullRequestState::Closed => title.bold().red(),
75            PullRequestState::Merged => title.bold().green(),
76            PullRequestState::Locked => title.bold().magenta(),
77        };
78        let branch = to_fixed_length(&self.source, SHORT_BRANCH_SIZE, true).blue();
79        let colored_id = format!("#{}", self.id).dimmed();
80        format!("{} {} {:>6}\n", title, branch, colored_id)
81    }
82}
83
84impl Formatter for Repository {
85    fn show_json(&self) -> String {
86        serde_json::to_string(&self).unwrap()
87    }
88    fn show_normal(&self) -> String {
89        let title_line = to_fixed_length(&self.full_name, TITLE_SIZE, true).bold();
90        let forked_line = if let Some(ref forked) = self.forked_from {
91            format!("{} {}\n", "forked from".dimmed(), forked.full_name)
92        } else {
93            String::new()
94        };
95        let counts_line = format!(
96            "{} stars, {} forks",
97            self.stars_count.to_string().yellow(),
98            self.forks_count.to_string().yellow(),
99        );
100        let description = if !self.description.is_empty() {
101            format!("\n{}\n---", self.description)
102        } else {
103            "".to_string()
104        };
105        let url_line = format!("{}", self.html_url.dimmed());
106
107        format!(
108            "{title_line}
109{forked_line}{counts_line}
110{description}
111{url_line}
112"
113        )
114    }
115    fn show_short(&self) -> String {
116        let title = to_fixed_length(&self.full_name, SHORT_TITLE_SIZE, true);
117        format!("{}\n", title)
118    }
119}