ok/jj
1
0
Fork 0
forked from mirrors/jj

styler: rename Styler to more standard Formatter

This commit is contained in:
Martin von Zweigbergk 2021-06-02 15:50:08 -07:00
parent d34a651087
commit b50ef1410d
7 changed files with 158 additions and 152 deletions

View file

@ -826,7 +826,7 @@ mod tests {
fn test_diff_real_case_write_fmt() {
// This is from src/ui.rs in commit f44d246e3f88 in this repo. It highlights the
// need for recursion into the range at the end: after splitting at "Arguments"
// and "styler", the region at the end has the unique words "write_fmt"
// and "formatter", the region at the end has the unique words "write_fmt"
// and "fmt", but we forgot to recurse into that region, so we ended up
// saying that "write_fmt(fmt).unwrap()" was replaced by b"write_fmt(fmt)".
assert_eq!(diff(

View file

@ -59,8 +59,8 @@ use pest::Parser;
use self::chrono::{FixedOffset, TimeZone, Utc};
use crate::commands::CommandError::UserError;
use crate::diff_edit::DiffEditError;
use crate::formatter::{ColorFormatter, Formatter};
use crate::graphlog::{AsciiGraphDrawer, Edge};
use crate::styler::{ColorStyler, Styler};
use crate::template_parser::TemplateParser;
use crate::templater::Template;
use crate::ui::Ui;
@ -938,7 +938,7 @@ fn cmd_files(
Ok(())
}
fn print_diff(left: &[u8], right: &[u8], styler: &mut dyn Styler) -> io::Result<()> {
fn print_diff(left: &[u8], right: &[u8], formatter: &mut dyn Formatter) -> io::Result<()> {
let num_context_lines = 3;
let mut context = VecDeque::new();
// Have we printed "..." for any skipped context?
@ -956,66 +956,66 @@ fn print_diff(left: &[u8], right: &[u8], styler: &mut dyn Styler) -> io::Result<
}
if !context_before {
for line in &context {
print_diff_line(styler, line)?;
print_diff_line(formatter, line)?;
}
context.clear();
context_before = true;
}
if !skipped_context {
styler.write_bytes(b" ...\n")?;
formatter.write_bytes(b" ...\n")?;
skipped_context = true;
}
}
} else {
for line in &context {
print_diff_line(styler, line)?;
print_diff_line(formatter, line)?;
}
context.clear();
print_diff_line(styler, &diff_line)?;
print_diff_line(formatter, &diff_line)?;
context_before = false;
skipped_context = false;
}
}
if !context_before {
for line in &context {
print_diff_line(styler, line)?;
print_diff_line(formatter, line)?;
}
}
Ok(())
}
fn print_diff_line(styler: &mut dyn Styler, diff_line: &DiffLine) -> io::Result<()> {
fn print_diff_line(formatter: &mut dyn Formatter, diff_line: &DiffLine) -> io::Result<()> {
if diff_line.has_left_content {
styler.add_label(String::from("left"))?;
styler.write_bytes(format!("{:>4}", diff_line.left_line_number).as_bytes())?;
styler.remove_label()?;
styler.write_bytes(b" ")?;
formatter.add_label(String::from("left"))?;
formatter.write_bytes(format!("{:>4}", diff_line.left_line_number).as_bytes())?;
formatter.remove_label()?;
formatter.write_bytes(b" ")?;
} else {
styler.write_bytes(b" ")?;
formatter.write_bytes(b" ")?;
}
if diff_line.has_right_content {
styler.add_label(String::from("right"))?;
styler.write_bytes(format!("{:>4}", diff_line.right_line_number).as_bytes())?;
styler.remove_label()?;
styler.write_bytes(b": ")?;
formatter.add_label(String::from("right"))?;
formatter.write_bytes(format!("{:>4}", diff_line.right_line_number).as_bytes())?;
formatter.remove_label()?;
formatter.write_bytes(b": ")?;
} else {
styler.write_bytes(b" : ")?;
formatter.write_bytes(b" : ")?;
}
for hunk in &diff_line.hunks {
match hunk {
files::DiffHunk::Unmodified(data) => {
styler.write_bytes(data)?;
formatter.write_bytes(data)?;
}
files::DiffHunk::Removed(data) => {
styler.add_label(String::from("left"))?;
styler.write_bytes(data)?;
styler.remove_label()?;
formatter.add_label(String::from("left"))?;
formatter.write_bytes(data)?;
formatter.remove_label()?;
}
files::DiffHunk::Added(data) => {
styler.add_label(String::from("right"))?;
styler.write_bytes(data)?;
styler.remove_label()?;
formatter.add_label(String::from("right"))?;
formatter.write_bytes(data)?;
formatter.remove_label()?;
}
}
}
@ -1055,8 +1055,8 @@ fn cmd_diff(
let summary = from_tree.diff_summary(&to_tree);
show_diff_summary(ui, repo.working_copy_path(), &summary)?;
} else {
let mut styler = ui.styler();
styler.add_label(String::from("diff"))?;
let mut formatter = ui.formatter();
formatter.add_label(String::from("diff"))?;
for (path, diff) in from_tree.diff(&to_tree) {
let ui_path = ui.format_file_path(repo.working_copy_path(), &path);
match diff {
@ -1064,11 +1064,11 @@ fn cmd_diff(
id,
executable: false,
}) => {
styler.add_label(String::from("header"))?;
styler.write_str(&format!("added file {}:\n", ui_path))?;
styler.remove_label()?;
formatter.add_label(String::from("header"))?;
formatter.write_str(&format!("added file {}:\n", ui_path))?;
formatter.remove_label()?;
let mut file_reader = repo.store().read_file(&path, &id).unwrap();
styler.write_from_reader(&mut file_reader)?;
formatter.write_from_reader(&mut file_reader)?;
}
Diff::Modified(
TreeValue::Normal {
@ -1080,13 +1080,13 @@ fn cmd_diff(
executable: right_executable,
},
) if left_executable == right_executable => {
styler.add_label(String::from("header"))?;
formatter.add_label(String::from("header"))?;
if left_executable {
styler.write_str(&format!("modified executable file {}:\n", ui_path))?;
formatter.write_str(&format!("modified executable file {}:\n", ui_path))?;
} else {
styler.write_str(&format!("modified file {}:\n", ui_path))?;
formatter.write_str(&format!("modified file {}:\n", ui_path))?;
}
styler.remove_label()?;
formatter.remove_label()?;
let mut file_reader_left = repo.store().read_file(&path, &id_left).unwrap();
let mut buffer_left = vec![];
@ -1098,7 +1098,7 @@ fn cmd_diff(
print_diff(
buffer_left.as_slice(),
buffer_right.as_slice(),
styler.as_mut(),
formatter.as_mut(),
)?;
}
Diff::Modified(
@ -1108,9 +1108,9 @@ fn cmd_diff(
executable: false,
},
) => {
styler.add_label(String::from("header"))?;
styler.write_str(&format!("resolved conflict in file {}:\n", ui_path))?;
styler.remove_label()?;
formatter.add_label(String::from("header"))?;
formatter.write_str(&format!("resolved conflict in file {}:\n", ui_path))?;
formatter.remove_label()?;
let conflict_left = repo.store().read_conflict(&id_left).unwrap();
let mut buffer_left = vec![];
@ -1127,7 +1127,7 @@ fn cmd_diff(
print_diff(
buffer_left.as_slice(),
buffer_right.as_slice(),
styler.as_mut(),
formatter.as_mut(),
)?;
}
Diff::Modified(
@ -1137,9 +1137,9 @@ fn cmd_diff(
},
TreeValue::Conflict(id_right),
) => {
styler.add_label(String::from("header"))?;
styler.write_str(&format!("new conflict in file {}:\n", ui_path))?;
styler.remove_label()?;
formatter.add_label(String::from("header"))?;
formatter.write_str(&format!("new conflict in file {}:\n", ui_path))?;
formatter.remove_label()?;
let mut file_reader_left = repo.store().read_file(&path, &id_left).unwrap();
let mut buffer_left = vec![];
file_reader_left.read_to_end(&mut buffer_left).unwrap();
@ -1155,30 +1155,30 @@ fn cmd_diff(
print_diff(
buffer_left.as_slice(),
buffer_right.as_slice(),
styler.as_mut(),
formatter.as_mut(),
)?;
}
Diff::Removed(TreeValue::Normal {
id,
executable: false,
}) => {
styler.add_label(String::from("header"))?;
styler.write_str(&format!("removed file {}:\n", ui_path))?;
styler.remove_label()?;
formatter.add_label(String::from("header"))?;
formatter.write_str(&format!("removed file {}:\n", ui_path))?;
formatter.remove_label()?;
let mut file_reader = repo.store().read_file(&path, &id).unwrap();
styler.write_from_reader(&mut file_reader)?;
formatter.write_from_reader(&mut file_reader)?;
}
other => {
writeln!(
styler,
formatter,
"unhandled diff case in path {:?}: {:?}",
path, other
)?;
}
}
}
styler.remove_label()?;
formatter.remove_label()?;
}
Ok(())
}
@ -1296,12 +1296,12 @@ fn cmd_log(
let template =
crate::template_parser::parse_commit_template(repo.as_repo_ref(), &template_string);
let mut styler = ui.styler();
let mut styler = styler.as_mut();
styler.add_label(String::from("log"))?;
let mut formatter = ui.formatter();
let mut formatter = formatter.as_mut();
formatter.add_label(String::from("log"))?;
if use_graph {
let mut graph = AsciiGraphDrawer::new(&mut styler);
let mut graph = AsciiGraphDrawer::new(&mut formatter);
for (index_entry, edges) in revset.iter().graph() {
let mut graphlog_edges = vec![];
// TODO: Should we update RevsetGraphIterator to yield this flag instead of all
@ -1330,9 +1330,9 @@ fn cmd_log(
// TODO: only use color if requested
{
let writer = Box::new(&mut buffer);
let mut styler = ColorStyler::new(writer, ui.settings());
let mut formatter = ColorFormatter::new(writer, ui.settings());
let commit = store.get_commit(&index_entry.commit_id()).unwrap();
template.format(&commit, &mut styler)?;
template.format(&commit, &mut formatter)?;
}
if !buffer.ends_with(b"\n") {
buffer.push(b'\n');
@ -1352,7 +1352,7 @@ fn cmd_log(
} else {
for index_entry in revset.iter() {
let commit = store.get_commit(&index_entry.commit_id()).unwrap();
template.format(&commit, styler)?;
template.format(&commit, formatter)?;
}
}
@ -1385,9 +1385,9 @@ fn cmd_obslog(
&template_string,
);
let mut styler = ui.styler();
let mut styler = styler.as_mut();
styler.add_label(String::from("log"))?;
let mut formatter = ui.formatter();
let mut formatter = formatter.as_mut();
formatter.add_label(String::from("log"))?;
let commits = topo_order_reverse(
vec![start_commit],
@ -1395,7 +1395,7 @@ fn cmd_obslog(
Box::new(|commit: &Commit| commit.predecessors()),
);
if use_graph {
let mut graph = AsciiGraphDrawer::new(&mut styler);
let mut graph = AsciiGraphDrawer::new(&mut formatter);
for commit in commits {
let mut edges = vec![];
for predecessor in commit.predecessors() {
@ -1405,8 +1405,8 @@ fn cmd_obslog(
// TODO: only use color if requested
{
let writer = Box::new(&mut buffer);
let mut styler = ColorStyler::new(writer, ui.settings());
template.format(&commit, &mut styler)?;
let mut formatter = ColorFormatter::new(writer, ui.settings());
template.format(&commit, &mut formatter)?;
}
if !buffer.ends_with(b"\n") {
buffer.push(b'\n');
@ -1420,7 +1420,7 @@ fn cmd_obslog(
}
} else {
for commit in commits {
template.format(&commit, styler)?;
template.format(&commit, formatter)?;
}
}
@ -2227,45 +2227,45 @@ fn cmd_op_log(
let repo = repo_command.repo();
let head_op = repo.operation().clone();
let head_op_id = head_op.id().clone();
let mut styler = ui.styler();
let mut styler = styler.as_mut();
let mut formatter = ui.formatter();
let mut formatter = formatter.as_mut();
struct OpTemplate;
impl Template<Operation> for OpTemplate {
fn format(&self, op: &Operation, styler: &mut dyn Styler) -> io::Result<()> {
fn format(&self, op: &Operation, formatter: &mut dyn Formatter) -> io::Result<()> {
// TODO: why can't this label be applied outside of the template?
styler.add_label("op-log".to_string())?;
formatter.add_label("op-log".to_string())?;
// TODO: Make this templated
styler.add_label("id".to_string())?;
styler.write_str(&op.id().hex()[0..12])?;
styler.remove_label()?;
styler.write_str(" ")?;
formatter.add_label("id".to_string())?;
formatter.write_str(&op.id().hex()[0..12])?;
formatter.remove_label()?;
formatter.write_str(" ")?;
let metadata = &op.store_operation().metadata;
styler.add_label("user".to_string())?;
styler.write_str(&format!("{}@{}", metadata.username, metadata.hostname))?;
styler.remove_label()?;
styler.write_str(" ")?;
styler.add_label("time".to_string())?;
styler.write_str(&format!(
formatter.add_label("user".to_string())?;
formatter.write_str(&format!("{}@{}", metadata.username, metadata.hostname))?;
formatter.remove_label()?;
formatter.write_str(" ")?;
formatter.add_label("time".to_string())?;
formatter.write_str(&format!(
"{} - {}",
format_timestamp(&metadata.start_time),
format_timestamp(&metadata.end_time)
))?;
styler.remove_label()?;
styler.write_str("\n")?;
styler.add_label("description".to_string())?;
styler.write_str(&metadata.description)?;
styler.remove_label()?;
formatter.remove_label()?;
formatter.write_str("\n")?;
formatter.add_label("description".to_string())?;
formatter.write_str(&metadata.description)?;
formatter.remove_label()?;
for (key, value) in &metadata.tags {
styler.write_str(&format!("\n{}: {}", key, value))?;
formatter.write_str(&format!("\n{}: {}", key, value))?;
}
styler.remove_label()?;
formatter.remove_label()?;
Ok(())
}
}
let template = OpTemplate;
let mut graph = AsciiGraphDrawer::new(&mut styler);
let mut graph = AsciiGraphDrawer::new(&mut formatter);
for op in topo_order_reverse(
vec![head_op],
Box::new(|op: &Operation| op.id().clone()),
@ -2279,8 +2279,8 @@ fn cmd_op_log(
// TODO: only use color if requested
{
let writer = Box::new(&mut buffer);
let mut styler = ColorStyler::new(writer, ui.settings());
template.format(&op, &mut styler)?;
let mut formatter = ColorFormatter::new(writer, ui.settings());
template.format(&op, &mut formatter)?;
}
if !buffer.ends_with(b"\n") {
buffer.push(b'\n');

View file

@ -19,7 +19,7 @@ use std::io::{Error, Read, Write};
use jujutsu_lib::settings::UserSettings;
// Lets the caller label strings and translates the labels to colors
pub trait Styler: Write {
pub trait Formatter: Write {
fn write_bytes(&mut self, data: &[u8]) -> io::Result<()> {
self.write_all(data)
}
@ -39,17 +39,17 @@ pub trait Styler: Write {
fn remove_label(&mut self) -> io::Result<()>;
}
pub struct PlainTextStyler<'a> {
output: Box<dyn Write + 'a>,
pub struct PlainTextFormatter<'output> {
output: Box<dyn Write + 'output>,
}
impl<'a> PlainTextStyler<'a> {
pub fn new(output: Box<dyn Write + 'a>) -> PlainTextStyler<'a> {
impl<'output> PlainTextFormatter<'output> {
pub fn new(output: Box<dyn Write + 'output>) -> PlainTextFormatter<'output> {
Self { output }
}
}
impl Write for PlainTextStyler<'_> {
impl Write for PlainTextFormatter<'_> {
fn write(&mut self, data: &[u8]) -> Result<usize, Error> {
self.output.write(data)
}
@ -59,7 +59,7 @@ impl Write for PlainTextStyler<'_> {
}
}
impl Styler for PlainTextStyler<'_> {
impl Formatter for PlainTextFormatter<'_> {
fn add_label(&mut self, _label: String) -> io::Result<()> {
Ok(())
}
@ -69,8 +69,8 @@ impl Styler for PlainTextStyler<'_> {
}
}
pub struct ColorStyler<'a> {
output: Box<dyn Write + 'a>,
pub struct ColorFormatter<'output> {
output: Box<dyn Write + 'output>,
colors: HashMap<String, String>,
labels: Vec<String>,
cached_colors: HashMap<Vec<String>, Vec<u8>>,
@ -111,9 +111,12 @@ fn config_colors(user_settings: &UserSettings) -> HashMap<String, String> {
result
}
impl<'a> ColorStyler<'a> {
pub fn new(output: Box<dyn Write + 'a>, user_settings: &UserSettings) -> ColorStyler<'a> {
ColorStyler {
impl<'output> ColorFormatter<'output> {
pub fn new(
output: Box<dyn Write + 'output>,
user_settings: &UserSettings,
) -> ColorFormatter<'output> {
ColorFormatter {
output,
colors: config_colors(user_settings),
labels: vec![],
@ -175,7 +178,7 @@ impl<'a> ColorStyler<'a> {
}
}
impl Write for ColorStyler<'_> {
impl Write for ColorFormatter<'_> {
fn write(&mut self, data: &[u8]) -> Result<usize, Error> {
self.output.write(data)
}
@ -185,7 +188,7 @@ impl Write for ColorStyler<'_> {
}
}
impl Styler for ColorStyler<'_> {
impl Formatter for ColorFormatter<'_> {
fn add_label(&mut self, label: String) -> io::Result<()> {
self.labels.push(label);
let new_color = self.current_color();

View file

@ -19,8 +19,8 @@ extern crate pest_derive;
pub mod commands;
pub mod diff_edit;
pub mod formatter;
pub mod graphlog;
pub mod styler;
pub mod template_parser;
pub mod templater;
pub mod ui;

View file

@ -21,7 +21,7 @@ use jujutsu_lib::store::{CommitId, Signature};
use pest::iterators::{Pair, Pairs};
use pest::Parser;
use crate::styler::PlainTextStyler;
use crate::formatter::PlainTextFormatter;
use crate::templater::{
AuthorProperty, ChangeIdProperty, CommitIdKeyword, CommitterProperty, ConditionalTemplate,
ConflictProperty, ConstantTemplateProperty, CurrentCheckoutProperty, DescriptionProperty,
@ -345,8 +345,8 @@ fn parse_commit_term<'a>(repo: RepoRef<'a>, pair: Pair<Rule>) -> Box<dyn Templat
let mut buf: Vec<u8> = vec![];
{
let writer = Box::new(&mut buf);
let mut styler = PlainTextStyler::new(writer);
label_template.format(commit, &mut styler).unwrap();
let mut formatter = PlainTextFormatter::new(writer);
label_template.format(commit, &mut formatter).unwrap();
}
String::from_utf8(buf).unwrap()
};

View file

@ -20,33 +20,36 @@ use jujutsu_lib::commit::Commit;
use jujutsu_lib::repo::RepoRef;
use jujutsu_lib::store::{CommitId, Signature};
use crate::styler::Styler;
use crate::formatter::Formatter;
pub trait Template<C> {
fn format(&self, context: &C, styler: &mut dyn Styler) -> io::Result<()>;
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()>;
}
// TODO: Extract a trait for this type?
pub struct TemplateFormatter<'s, 't: 's, C> {
pub struct TemplateFormatter<'f, 't: 'f, C> {
template: Box<dyn Template<C> + 't>,
styler: &'s mut dyn Styler,
formatter: &'f mut dyn Formatter,
}
impl<'s, 't: 's, C> TemplateFormatter<'s, 't, C> {
pub fn new(template: Box<dyn Template<C> + 't>, styler: &'s mut dyn Styler) -> Self {
TemplateFormatter { template, styler }
impl<'f, 't: 'f, C> TemplateFormatter<'f, 't, C> {
pub fn new(template: Box<dyn Template<C> + 't>, formatter: &'f mut dyn Formatter) -> Self {
TemplateFormatter {
template,
formatter,
}
}
pub fn format<'c, 'a: 'c>(&'a mut self, context: &'c C) -> io::Result<()> {
self.template.format(context, self.styler.borrow_mut())
self.template.format(context, self.formatter.borrow_mut())
}
}
pub struct LiteralTemplate(pub String);
impl<C> Template<C> for LiteralTemplate {
fn format(&self, _context: &C, styler: &mut dyn Styler) -> io::Result<()> {
styler.write_str(&self.0)
fn format(&self, _context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
formatter.write_str(&self.0)
}
}
@ -67,13 +70,13 @@ impl<'a, C> LabelTemplate<'a, C> {
}
impl<'a, C> Template<C> for LabelTemplate<'a, C> {
fn format(&self, context: &C, styler: &mut dyn Styler) -> io::Result<()> {
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
for label in &self.labels {
styler.add_label(label.clone())?;
formatter.add_label(label.clone())?;
}
self.content.format(context, styler)?;
self.content.format(context, formatter)?;
for _label in &self.labels {
styler.remove_label()?;
formatter.remove_label()?;
}
Ok(())
}
@ -98,18 +101,18 @@ impl<'a, C> DynamicLabelTemplate<'a, C> {
}
impl<'a, C> Template<C> for DynamicLabelTemplate<'a, C> {
fn format(&self, context: &C, styler: &mut dyn Styler) -> io::Result<()> {
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
let labels = self.label_property.as_ref()(context);
let labels: Vec<String> = labels
.split_whitespace()
.map(|label| label.to_string())
.collect();
for label in &labels {
styler.add_label(label.clone())?;
formatter.add_label(label.clone())?;
}
self.content.format(context, styler)?;
self.content.format(context, formatter)?;
for _label in &labels {
styler.remove_label()?;
formatter.remove_label()?;
}
Ok(())
}
@ -119,9 +122,9 @@ impl<'a, C> Template<C> for DynamicLabelTemplate<'a, C> {
pub struct ListTemplate<'a, C>(pub Vec<Box<dyn Template<C> + 'a>>);
impl<'a, C> Template<C> for ListTemplate<'a, C> {
fn format(&self, context: &C, styler: &mut dyn Styler) -> io::Result<()> {
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
for template in &self.0 {
template.format(context, styler)?
template.format(context, formatter)?
}
Ok(())
}
@ -147,9 +150,9 @@ pub struct StringPropertyTemplate<'a, C> {
}
impl<'a, C> Template<C> for StringPropertyTemplate<'a, C> {
fn format(&self, context: &C, styler: &mut dyn Styler) -> io::Result<()> {
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
let text = self.property.extract(context);
styler.write_str(&text)
formatter.write_str(&text)
}
}
@ -294,11 +297,11 @@ impl<'a, C> ConditionalTemplate<'a, C> {
}
impl<'a, C> Template<C> for ConditionalTemplate<'a, C> {
fn format(&self, context: &C, styler: &mut dyn Styler) -> io::Result<()> {
fn format(&self, context: &C, formatter: &mut dyn Formatter) -> io::Result<()> {
if self.condition.extract(context) {
self.true_template.format(context, styler)?;
self.true_template.format(context, formatter)?;
} else if let Some(false_template) = &self.false_template {
false_template.format(context, styler)?;
false_template.format(context, formatter)?;
}
Ok(())
}

View file

@ -22,31 +22,31 @@ use jujutsu_lib::repo::RepoRef;
use jujutsu_lib::repo_path::RepoPath;
use jujutsu_lib::settings::UserSettings;
use crate::styler::{ColorStyler, PlainTextStyler, Styler};
use crate::formatter::{ColorFormatter, Formatter, PlainTextFormatter};
use crate::templater::TemplateFormatter;
pub struct Ui<'a> {
cwd: PathBuf,
styler: Mutex<Box<dyn Styler + 'a>>,
formatter: Mutex<Box<dyn Formatter + 'a>>,
settings: UserSettings,
}
impl<'a> Ui<'a> {
impl<'stdout> Ui<'stdout> {
pub fn new(
cwd: PathBuf,
stdout: Box<dyn Write + 'a>,
stdout: Box<dyn Write + 'stdout>,
is_atty: bool,
settings: UserSettings,
) -> Ui<'a> {
let styler: Box<dyn Styler + 'a> = if is_atty {
Box::new(ColorStyler::new(stdout, &settings))
) -> Ui<'stdout> {
let formatter: Box<dyn Formatter + 'stdout> = if is_atty {
Box::new(ColorFormatter::new(stdout, &settings))
} else {
Box::new(PlainTextStyler::new(stdout))
Box::new(PlainTextFormatter::new(stdout))
};
let styler = Mutex::new(styler);
let formatter = Mutex::new(formatter);
Ui {
cwd,
styler,
formatter,
settings,
}
}
@ -65,23 +65,23 @@ impl<'a> Ui<'a> {
&self.settings
}
pub fn styler(&self) -> MutexGuard<Box<dyn Styler + 'a>> {
self.styler.lock().unwrap()
pub fn formatter(&self) -> MutexGuard<Box<dyn Formatter + 'stdout>> {
self.formatter.lock().unwrap()
}
pub fn write(&mut self, text: &str) -> io::Result<()> {
self.styler().write_str(text)
self.formatter().write_str(text)
}
pub fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
self.styler().write_fmt(fmt)
self.formatter().write_fmt(fmt)
}
pub fn write_error(&mut self, text: &str) -> io::Result<()> {
let mut styler = self.styler();
styler.add_label(String::from("error"))?;
styler.write_str(text)?;
styler.remove_label()?;
let mut formatter = self.formatter();
formatter.add_label(String::from("error"))?;
formatter.write_str(text)?;
formatter.remove_label()?;
Ok(())
}
@ -96,8 +96,8 @@ impl<'a> Ui<'a> {
)
});
let template = crate::template_parser::parse_commit_template(repo, &template_string);
let mut styler = self.styler();
let mut template_writer = TemplateFormatter::new(template, styler.as_mut());
let mut formatter = self.formatter();
let mut template_writer = TemplateFormatter::new(template, formatter.as_mut());
template_writer.format(commit)?;
Ok(())
}