use crate::cli::style::{Stream, Stylize, check, cross, hyperlink_url};
use anstream::{eprintln, print, println};
use async_trait::async_trait;
use jj_ryu::error::Error;
use jj_ryu::submit::{Phase, ProgressCallback, PushStatus};
use jj_ryu::types::PullRequest;
use std::io::Write;
pub struct CliProgress {
pub verbose: bool,
}
impl CliProgress {
pub const fn verbose() -> Self {
Self { verbose: true }
}
pub const fn compact() -> Self {
Self { verbose: false }
}
}
#[async_trait]
impl ProgressCallback for CliProgress {
async fn on_phase(&self, phase: Phase) {
if self.verbose {
println!("{}...", phase.to_string().emphasis());
} else {
match phase {
Phase::Executing | Phase::AddingComments => {
println!(" {}...", phase.to_string().muted());
}
_ => {}
}
}
}
async fn on_bookmark_push(&self, bookmark: &str, status: PushStatus) {
if self.verbose {
match &status {
PushStatus::Started => {
println!(" Pushing {}...", bookmark.accent());
}
PushStatus::Success => {
println!(" {} Pushed {}", check(), bookmark.emphasis());
}
PushStatus::AlreadySynced => {
println!(
" {} {} {}",
"-".muted(),
bookmark.accent(),
status.to_string().muted()
);
}
PushStatus::Failed(_) => {
eprintln!(
" {} Failed to push {}: {}",
cross(),
bookmark.accent().for_stderr(),
status.to_string().error()
);
}
}
} else {
match &status {
PushStatus::Started => {
print!(" Pushing {}... ", bookmark.accent());
let _ = std::io::stdout().flush();
}
PushStatus::Success => {
println!("{}", "done".success());
}
_ => {
println!("{}", status.to_string().warn().for_stdout());
}
}
}
}
async fn on_pr_created(&self, bookmark: &str, pr: &PullRequest) {
let pr_num = format!("#{}", pr.number);
if self.verbose {
println!(
" {} Created PR {} for {}",
check(),
pr_num.accent(),
bookmark.emphasis()
);
println!(" {}", hyperlink_url(Stream::Stdout, &pr.html_url));
} else {
println!(
" Created PR {} for {} ({})",
pr_num.accent(),
bookmark.accent(),
hyperlink_url(Stream::Stdout, &pr.html_url)
);
}
}
async fn on_pr_updated(&self, bookmark: &str, pr: &PullRequest) {
let pr_num = format!("#{}", pr.number);
if self.verbose {
println!(
" {} Updated PR {} for {}",
check(),
pr_num.accent(),
bookmark.emphasis()
);
} else {
println!(
" Updated PR {} for {}",
pr_num.accent(),
bookmark.accent()
);
}
}
async fn on_error(&self, err: &Error) {
if self.verbose {
eprintln!("{}: {}", "error".error(), err);
} else {
eprintln!(" {}: {}", "error".error(), err);
}
}
async fn on_message(&self, message: &str) {
if self.verbose {
println!("{message}");
} else {
println!(" {}", message.muted());
}
}
}