term: Rename print to println

The name `print` was used because, previously, the `println`
function name was taken.

This has now changed, allowing the rename of this function to happen.
This commit is contained in:
Fintan Halpenny 2026-04-03 07:51:32 +01:00 committed by Lorenz Leutgeb
parent e7d519cf65
commit 2262b8d9bd
23 changed files with 78 additions and 78 deletions

View File

@ -158,10 +158,10 @@ pub fn authenticate(args: Args, profile: &Profile) -> anyhow::Result<()> {
return Ok(()); return Ok(());
} }
term::print(term::format::dim( term::println(term::format::dim(
"Nothing to do, ssh-agent is not running.", "Nothing to do, ssh-agent is not running.",
)); ));
term::print(term::format::dim( term::println(term::format::dim(
"You will be prompted for a passphrase when necessary.", "You will be prompted for a passphrase when necessary.",
)); ));

View File

@ -80,7 +80,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
oid oid
} }
}; };
term::print(oid); term::println(oid);
} }
Migrate => { Migrate => {
let mut db = profile.cobs_db_mut()?; let mut db = profile.cobs_db_mut()?;
@ -100,7 +100,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
FilteredTypeName::from(type_name).as_ref(), FilteredTypeName::from(type_name).as_ref(),
)?; )?;
for cob in cobs { for cob in cobs {
term::print(cob.id); term::println(cob.id);
} }
} }
Log { Log {
@ -215,7 +215,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
} }
}; };
term::print(oid); term::println(oid);
} }
} }
Ok(()) Ok(())
@ -303,18 +303,18 @@ where
std::time::UNIX_EPOCH + std::time::Duration::from_secs(op.timestamp.as_secs()), std::time::UNIX_EPOCH + std::time::Duration::from_secs(op.timestamp.as_secs()),
) )
.to_rfc2822(); .to_rfc2822();
term::print(term::format::yellow(format!("commit {}", op.id))); term::println(term::format::yellow(format!("commit {}", op.id)));
if let Some(oid) = op.identity { if let Some(oid) = op.identity {
term::print(term::format::tertiary(format!("resource {oid}"))); term::println(term::format::tertiary(format!("resource {oid}")));
} }
for parent in op.parents { for parent in op.parents {
term::print(format!("parent {parent}")); term::println(format!("parent {parent}"));
} }
for parent in op.related { for parent in op.related {
term::print(format!("rel {parent}")); term::println(format!("rel {parent}"));
} }
term::print(format!("author {}", op.author)); term::println(format!("author {}", op.author));
term::print(format!("date {time}")); term::println(format!("date {time}"));
term::blank(); term::blank();
for action in op.actions { for action in op.actions {
let val = serde_json::to_string_pretty(&action)?; let val = serde_json::to_string_pretty(&action)?;
@ -330,7 +330,7 @@ fn print_op_json<A>(op: cob::Op<A>) -> anyhow::Result<()>
where where
A: serde::Serialize, A: serde::Serialize,
{ {
term::print(serde_json::to_value(&op)?); term::println(serde_json::to_value(&op)?);
Ok(()) Ok(())
} }

View File

@ -102,10 +102,10 @@ where
fn print_value(value: &serde_json::Value) -> anyhow::Result<()> { fn print_value(value: &serde_json::Value) -> anyhow::Result<()> {
match value { match value {
serde_json::Value::Null => {} serde_json::Value::Null => {}
serde_json::Value::Bool(b) => term::print(b), serde_json::Value::Bool(b) => term::println(b),
serde_json::Value::Array(a) => a.iter().try_for_each(print_value)?, serde_json::Value::Array(a) => a.iter().try_for_each(print_value)?,
serde_json::Value::Number(n) => term::print(n), serde_json::Value::Number(n) => term::println(n),
serde_json::Value::String(s) => term::print(s), serde_json::Value::String(s) => term::println(s),
serde_json::Value::Object(o) => { serde_json::Value::Object(o) => {
term::json::to_pretty(&o, Path::new("config.json"))?.print() term::json::to_pretty(&o, Path::new("config.json"))?.print()
} }

View File

@ -60,7 +60,7 @@ fn debug(profile: Option<&Profile>) -> anyhow::Result<()> {
warnings: collect_warnings(profile), warnings: collect_warnings(profile),
}; };
term::print(serde_json::to_string_pretty(&debug).unwrap()); term::println(serde_json::to_string_pretty(&debug).unwrap());
Ok(()) Ok(())
} }

View File

@ -167,7 +167,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
{ {
Some(proposal) => serde_json::from_str::<RawDoc>(&proposal)?, Some(proposal) => serde_json::from_str::<RawDoc>(&proposal)?,
None => { None => {
term::print(term::format::italic( term::println(term::format::italic(
"Nothing to do. The document is up to date. See `rad inspect --identity`.", "Nothing to do. The document is up to date. See `rad inspect --identity`.",
)); ));
return Ok(()); return Ok(());
@ -180,7 +180,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
let proposal = update::verify(proposal)?; let proposal = update::verify(proposal)?;
if proposal == current.doc { if proposal == current.doc {
if !args.quiet { if !args.quiet {
term::print(term::format::italic( term::println(term::format::italic(
"Nothing to do. The document is up to date. See `rad inspect --identity`.", "Nothing to do. The document is up to date. See `rad inspect --identity`.",
)); ));
} }
@ -193,7 +193,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
repo.set_identity_head_to(revision.id)?; repo.set_identity_head_to(revision.id)?;
} }
if args.quiet { if args.quiet {
term::print(revision.id); term::println(revision.id);
} else { } else {
term::success!( term::success!(
"Identity revision {} created", "Identity revision {} created",
@ -516,7 +516,7 @@ fn print_diff(
let diff = modified.diff.to_unified_string()?; let diff = modified.diff.to_unified_string()?;
term::print_inline(diff); term::print_inline(diff);
} else { } else {
term::print(term::format::italic("No changes.")); term::println(term::format::italic("No changes."));
} }
Ok(()) Ok(())
} }

View File

@ -96,7 +96,7 @@ fn list(
}; };
if repos.is_empty() { if repos.is_empty() {
term::print(term::format::italic("Your inbox is empty.")); term::println(term::format::italic("Your inbox is empty."));
} else { } else {
for repo in repos { for repo in repos {
repo.print(); repo.print();
@ -397,7 +397,7 @@ fn clear(notifs: &mut notifications::StoreWriter, mode: ClearMode) -> anyhow::Re
if cleared > 0 { if cleared > 0 {
term::success!("Cleared {cleared} item(s) from your inbox"); term::success!("Cleared {cleared} item(s) from your inbox");
} else { } else {
term::print(term::format::italic("Your inbox is empty.")); term::println(term::format::italic("Your inbox is empty."));
} }
Ok(()) Ok(())
} }

View File

@ -68,7 +68,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
let refs = RefsAt::new(&repo, remote)?; let refs = RefsAt::new(&repo, remote)?;
let sigrefs = SignedRefs::load_at(refs.at, remote, &repo); let sigrefs = SignedRefs::load_at(refs.at, remote, &repo);
term::print(format_args!( term::println(format_args!(
"{:<48} {} {}", "{:<48} {} {}",
term::format::tertiary(remote.to_human()), term::format::tertiary(remote.to_human()),
term::format::secondary(refs.at), term::format::secondary(refs.at),
@ -111,7 +111,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
let seed = policies.seed_policy(&rid)?; let seed = policies.seed_policy(&rid)?;
match seed.policy { match seed.policy {
SeedingPolicy::Allow { scope } => { SeedingPolicy::Allow { scope } => {
term::print(format_args!( term::println(format_args!(
"Repository {} is {} with scope {}", "Repository {} is {} with scope {}",
term::format::tertiary(&rid), term::format::tertiary(&rid),
term::format::positive("being seeded"), term::format::positive("being seeded"),
@ -119,7 +119,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
)); ));
} }
SeedingPolicy::Block => { SeedingPolicy::Block => {
term::print(format_args!( term::println(format_args!(
"Repository {} is {}", "Repository {} is {}",
term::format::tertiary(&rid), term::format::tertiary(&rid),
term::format::negative("not being seeded"), term::format::negative("not being seeded"),
@ -132,19 +132,19 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
let aliases = profile.aliases(); let aliases = profile.aliases();
for did in doc.delegates().iter() { for did in doc.delegates().iter() {
if let Some(alias) = aliases.alias(did) { if let Some(alias) = aliases.alias(did) {
term::print(format_args!( term::println(format_args!(
"{} {}", "{} {}",
term::format::tertiary(&did), term::format::tertiary(&did),
term::format::parens(term::format::dim(alias)) term::format::parens(term::format::dim(alias))
)); ));
} else { } else {
term::print(term::format::tertiary(&did)); term::println(term::format::tertiary(&did));
} }
} }
} }
Target::Visibility => { Target::Visibility => {
let (_, doc) = repo(rid, storage)?; let (_, doc) = repo(rid, storage)?;
term::print(term::format::visibility(doc.visibility())); term::println(term::format::visibility(doc.visibility()));
} }
Target::History => { Target::History => {
let (repo, _) = repo(rid, storage)?; let (repo, _) = repo(rid, storage)?;
@ -177,16 +177,16 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
.with_timezone(&timezone) .with_timezone(&timezone)
.to_rfc2822(); .to_rfc2822();
term::print(format_args!( term::println(format_args!(
"{} {}", "{} {}",
term::format::yellow("commit"), term::format::yellow("commit"),
term::format::yellow(oid), term::format::yellow(oid),
)); ));
if let Ok(parent) = tip.parent_id(0) { if let Ok(parent) = tip.parent_id(0) {
term::print(format_args!("parent {parent}")); term::println(format_args!("parent {parent}"));
} }
term::print(format_args!("blob {}", revision.blob)); term::println(format_args!("blob {}", revision.blob));
term::print(format_args!("date {time}")); term::println(format_args!("date {time}"));
term::blank(); term::blank();
if let Some(msg) = tip.message() { if let Some(msg) = tip.message() {
@ -200,7 +200,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
term::blank(); term::blank();
} }
for line in json::to_pretty(&doc, Path::new("radicle.json"))? { for line in json::to_pretty(&doc, Path::new("radicle.json"))? {
term::print(format_args!(" {line}")); term::println(format_args!(" {line}"));
} }
term::blank(); term::blank();

View File

@ -239,7 +239,7 @@ where
C: issue::cache::Issues, C: issue::cache::Issues,
{ {
if cache.is_empty()? { if cache.is_empty()? {
term::print(term::format::italic("Nothing to show.")); term::println(term::format::italic("Nothing to show."));
return Ok(()); return Ok(());
} }

View File

@ -39,7 +39,7 @@ where
let comment_id = issue.comment(body, reply_to.unwrap_or(*root_comment_id), vec![])?; let comment_id = issue.comment(body, reply_to.unwrap_or(*root_comment_id), vec![])?;
if quiet { if quiet {
term::print(comment_id); term::println(comment_id);
} else { } else {
let comment = issue.thread().comment(&comment_id).unwrap(); let comment = issue.thread().comment(&comment_id).unwrap();
term::comment::widget(&comment_id, comment, profile).print(); term::comment::widget(&comment_id, comment, profile).print();
@ -82,7 +82,7 @@ where
)?; )?;
issue.edit_comment(comment_id, body, vec![])?; issue.edit_comment(comment_id, body, vec![])?;
if quiet { if quiet {
term::print(comment_id); term::println(comment_id);
} else { } else {
let comment = issue.thread().comment(&comment_id).unwrap(); let comment = issue.thread().comment(&comment_id).unwrap();
term::comment::widget(&comment_id, comment, profile).print(); term::comment::widget(&comment_id, comment, profile).print();

View File

@ -69,7 +69,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
rows.sort(); rows.sort();
if rows.is_empty() { if rows.is_empty() {
term::print(term::format::italic("Nothing to show.")); term::println(term::format::italic("Nothing to show."));
} else { } else {
table.header([ table.header([
"Name".into(), "Name".into(),

View File

@ -47,7 +47,7 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
if addresses { if addresses {
let cfg = node.config()?; let cfg = node.config()?;
for addr in cfg.external_addresses { for addr in cfg.external_addresses {
term::print(ConnectAddress::from((*profile.id(), addr)).to_string()); term::println(ConnectAddress::from((*profile.id(), addr)).to_string());
} }
} else { } else {
control::config(&node)?; control::config(&node)?;
@ -88,14 +88,14 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
Command::Inventory { nid } => { Command::Inventory { nid } => {
let nid = nid.as_ref().unwrap_or(profile.id()); let nid = nid.as_ref().unwrap_or(profile.id());
for rid in profile.routing()?.get_inventory(nid)? { for rid in profile.routing()?.get_inventory(nid)? {
term::print(term::format::tertiary(rid)); term::println(term::format::tertiary(rid));
} }
} }
Command::Status { Command::Status {
only: Some(Only::Nid), only: Some(Only::Nid),
} => { } => {
if node.is_running() { if node.is_running() {
term::print(term::format::node_id_human(&node.nid()?)); term::println(term::format::node_id_human(&node.nid()?));
} else { } else {
process::exit(2); process::exit(2);
} }

View File

@ -13,7 +13,7 @@ pub fn db(profile: &Profile, op: DbOperation) -> anyhow::Result<()> {
if changed > 0 { if changed > 0 {
term::success!("{changed} row(s) affected."); term::success!("{changed} row(s) affected.");
} else { } else {
term::print(term::format::italic("No rows affected.")); term::println(term::format::italic("No rows affected."));
} }
} }
} }

View File

@ -83,7 +83,7 @@ pub fn start(
spinner.message(format!("Node started {pid}")); spinner.message(format!("Node started {pid}"));
spinner.finish(); spinner.finish();
term::print(term::format::dim( term::println(term::format::dim(
"To stay in sync with the network, leave the node running in the background.", "To stay in sync with the network, leave the node running in the background.",
)); ));
term::info!( term::info!(
@ -414,7 +414,7 @@ pub fn config(node: &Node) -> anyhow::Result<()> {
let cfg = node.config()?; let cfg = node.config()?;
let cfg = serde_json::to_string_pretty(&cfg)?; let cfg = serde_json::to_string_pretty(&cfg)?;
term::print(cfg); term::println(cfg);
Ok(()) Ok(())
} }

View File

@ -13,7 +13,7 @@ where
let event = event?; let event = event?;
let obj = serde_json::to_string(&event)?; let obj = serde_json::to_string(&event)?;
term::print(&obj); term::println(&obj);
// Only output up to `count` events. // Only output up to `count` events.
if i + 1 >= count { if i + 1 >= count {

View File

@ -44,6 +44,6 @@ fn print_table(entries: impl IntoIterator<Item = (RepoId, NodeId)>) {
fn print_json(entries: impl IntoIterator<Item = (RepoId, NodeId)>) { fn print_json(entries: impl IntoIterator<Item = (RepoId, NodeId)>) {
for (rid, nid) in entries { for (rid, nid) in entries {
term::print(serde_json::json!({ "rid": rid, "nid": nid })); term::println(serde_json::json!({ "rid": rid, "nid": nid }));
} }
} }

View File

@ -46,7 +46,7 @@ pub fn run(
.ok_or(anyhow!("error retrieving comment `{comment_id}`"))?; .ok_or(anyhow!("error retrieving comment `{comment_id}`"))?;
if quiet { if quiet {
term::print(comment_id); term::println(comment_id);
} else { } else {
term::comment::widget(&comment_id, comment, profile).print(); term::comment::widget(&comment_id, comment, profile).print();
} }

View File

@ -46,7 +46,7 @@ pub fn run(
} }
if all.is_empty() { if all.is_empty() {
term::print(term::format::italic("Nothing to show.")); term::println(term::format::italic("Nothing to show."));
return Ok(()); return Ok(());
} }

View File

@ -48,7 +48,7 @@ pub fn run(
let message = term::patch::get_update_message(message, workdir, revision, &head_oid.into())?; let message = term::patch::get_update_message(message, workdir, revision, &head_oid.into())?;
let revision = patch.update(message, base_oid, head_oid)?; let revision = patch.update(message, base_oid, head_oid)?;
term::print(revision); term::println(revision);
Ok(()) Ok(())
} }

View File

@ -9,7 +9,7 @@ pub use args::Args;
pub fn run(_args: Args, _ctx: impl term::Context) -> anyhow::Result<()> { pub fn run(_args: Args, _ctx: impl term::Context) -> anyhow::Result<()> {
let home = profile::home()?; let home = profile::home()?;
term::print(home.path().display()); term::println(home.path().display());
Ok(()) Ok(())
} }

View File

@ -112,7 +112,7 @@ pub fn seeding(profile: &Profile) -> anyhow::Result<()> {
} }
if t.is_empty() { if t.is_empty() {
term::print(term::format::dim("No seeding policies to show.")); term::println(term::format::dim("No seeding policies to show."));
} else { } else {
t.print(); t.print();
} }

View File

@ -14,20 +14,20 @@ pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
let profile = ctx.profile()?; let profile = ctx.profile()?;
if args.did { if args.did {
term::print(profile.did()); term::println(profile.did());
} else if args.alias { } else if args.alias {
term::print(profile.config.alias()); term::println(profile.config.alias());
} else if args.home { } else if args.home {
term::print(profile.home().path().display()); term::println(profile.home().path().display());
} else if args.ssh_key { } else if args.ssh_key {
term::print(ssh::fmt::key(profile.id())); term::println(ssh::fmt::key(profile.id()));
} else if args.config { } else if args.config {
term::print(profile.home.config().display()); term::println(profile.home.config().display());
} else if args.ssh_fingerprint { } else if args.ssh_fingerprint {
term::print(ssh::fmt::fingerprint(profile.id())); term::println(ssh::fmt::fingerprint(profile.id()));
} else if args.nid { } else if args.nid {
crate::warning::deprecated("rad self --nid", "rad node status --only nid"); crate::warning::deprecated("rad self --nid", "rad node status --only nid");
term::print( term::println(
Node::new(profile.socket_from_env()) Node::new(profile.socket_from_env())
.nid() .nid()
.ok() .ok()

View File

@ -198,7 +198,7 @@ fn announce_refs(
}; };
if let Err(e) = repo.remote(&profile.public_key) { if let Err(e) = repo.remote(&profile.public_key) {
if e.is_not_found() { if e.is_not_found() {
term::print(term::format::italic( term::println(term::format::italic(
"Nothing to announce, you don't have a fork of this repository.", "Nothing to announce, you don't have a fork of this repository.",
)); ));
return Ok(()); return Ok(());

View File

@ -74,7 +74,7 @@ macro_rules! info {
writeln!($writer, $($arg)*).ok(); writeln!($writer, $($arg)*).ok();
}); });
($($arg:tt)*) => ({ ($($arg:tt)*) => ({
$crate::io::print(format_args!($($arg)*)); $crate::io::println(format_args!($($arg)*));
}) })
} }
@ -118,7 +118,7 @@ pub fn success_args<W: io::Write>(w: &mut W, args: fmt::Arguments) {
} }
pub fn tip_args(args: fmt::Arguments) { pub fn tip_args(args: fmt::Arguments) {
print(format_args!( println(format_args!(
"{} {}", "{} {}",
format::yellow("*"), format::yellow("*"),
style(format!("{args}")).italic() style(format!("{args}")).italic()
@ -148,23 +148,23 @@ pub fn viewport() -> Option<Size> {
} }
pub fn headline(headline: impl fmt::Display) { pub fn headline(headline: impl fmt::Display) {
print(""); println("");
print(style(headline).bold()); println(style(headline).bold());
print(""); println("");
} }
pub fn header(header: &str) { pub fn header(header: &str) {
print(""); println("");
print(style(format::yellow(header)).bold().underline()); println(style(format::yellow(header)).bold().underline());
print(""); println("");
} }
pub fn blob(text: impl fmt::Display) { pub fn blob(text: impl fmt::Display) {
print(style(text.to_string().trim()).dim()); println(style(text.to_string().trim()).dim());
} }
pub fn blank() { pub fn blank() {
print(""); println("");
} }
/// Print a line to stdout, silently ignoring broken pipe errors. /// Print a line to stdout, silently ignoring broken pipe errors.
@ -177,7 +177,7 @@ pub fn blank() {
/// # Panics /// # Panics
/// ///
/// If writing to standard output fails with an error not of kind [`io::ErrorKind::BrokenPipe`]. /// If writing to standard output fails with an error not of kind [`io::ErrorKind::BrokenPipe`].
pub fn print(msg: impl fmt::Display) { pub fn println(msg: impl fmt::Display) {
use io::Write; use io::Write;
let mut stdout = io::stdout().lock(); let mut stdout = io::stdout().lock();
@ -190,7 +190,7 @@ pub fn print(msg: impl fmt::Display) {
/// Use this function instead of [`print!`] when you want to print to standard /// Use this function instead of [`print!`] when you want to print to standard
/// output, but silently ignore broken pipe errors. /// output, but silently ignore broken pipe errors.
/// ///
/// See also [`self::print`]. /// See also [`self::println`].
/// ///
/// # Panics /// # Panics
/// ///
@ -228,7 +228,7 @@ pub fn prefixed(prefix: &str, text: &str) -> String {
} }
pub fn help(name: &str, version: &str, description: &str, usage: &str) { pub fn help(name: &str, version: &str, description: &str, usage: &str) {
print(format_args!("rad-{name} {version}\n{description}\n{usage}")); println(format_args!("rad-{name} {version}\n{description}\n{usage}"));
} }
pub fn manual(name: &str) -> io::Result<process::ExitStatus> { pub fn manual(name: &str) -> io::Result<process::ExitStatus> {
@ -241,7 +241,7 @@ pub fn manual(name: &str) -> io::Result<process::ExitStatus> {
} }
pub fn usage(name: &str, usage: &str) { pub fn usage(name: &str, usage: &str) {
print(format_args!( println(format_args!(
"{} {}\n{}", "{} {}\n{}",
PREFIX_ERROR, PREFIX_ERROR,
Paint::red(format!("Error: rad-{name}: invalid usage")), Paint::red(format!("Error: rad-{name}: invalid usage")),
@ -250,19 +250,19 @@ pub fn usage(name: &str, usage: &str) {
} }
pub fn println_prefixed(prefix: impl fmt::Display, msg: impl fmt::Display) { pub fn println_prefixed(prefix: impl fmt::Display, msg: impl fmt::Display) {
print(format_args!("{prefix} {msg}")); println(format_args!("{prefix} {msg}"));
} }
pub fn indented(msg: impl fmt::Display) { pub fn indented(msg: impl fmt::Display) {
print(format_args!("{TAB}{msg}")); println(format_args!("{TAB}{msg}"));
} }
pub fn subcommand(msg: impl fmt::Display) { pub fn subcommand(msg: impl fmt::Display) {
print(style(format!("Running `{msg}`...")).dim()); println(style(format!("Running `{msg}`...")).dim());
} }
pub fn warning(warning: impl fmt::Display) { pub fn warning(warning: impl fmt::Display) {
print(format_args!( println(format_args!(
"{} {} {warning}", "{} {} {warning}",
PREFIX_WARNING, PREFIX_WARNING,
Paint::yellow("Warning:").bold(), Paint::yellow("Warning:").bold(),
@ -270,14 +270,14 @@ pub fn warning(warning: impl fmt::Display) {
} }
pub fn error(error: impl fmt::Display) { pub fn error(error: impl fmt::Display) {
print(format_args!( println(format_args!(
"{PREFIX_ERROR} {} {error}", "{PREFIX_ERROR} {} {error}",
Paint::red("Error:") Paint::red("Error:")
)); ));
} }
pub fn hint(hint: impl fmt::Display) { pub fn hint(hint: impl fmt::Display) {
print(format::hint(format!("{SYMBOL_ERROR} Hint: {hint}"))); println(format::hint(format!("{SYMBOL_ERROR} Hint: {hint}")));
} }
pub fn ask<D: fmt::Display>(prompt: D, default: bool) -> bool { pub fn ask<D: fmt::Display>(prompt: D, default: bool) -> bool {