forked from mirrors/jj
styler: rename Styler to more standard Formatter
This commit is contained in:
parent
d34a651087
commit
b50ef1410d
7 changed files with 158 additions and 152 deletions
|
@ -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(
|
||||
|
|
176
src/commands.rs
176
src/commands.rs
|
@ -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');
|
||||
|
|
|
@ -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();
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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(())
|
||||
}
|
||||
|
|
40
src/ui.rs
40
src/ui.rs
|
@ -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(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue