Migrate interpolated service messages to the t! macro (8 modules)

This commit is contained in:
Jean Chevronnet 2026-07-19 23:22:56 +00:00
parent b462d37bd5
commit d207c3d60d
No known key found for this signature in database
133 changed files with 782 additions and 702 deletions

View file

@ -1,4 +1,4 @@
use echo_api::{Sender, ServiceCtx, Store};
use echo_api::{t, Sender, ServiceCtx, Store};
// CANCEL <nick>: recall the last unread memo you sent to <nick>. A memo the
// recipient has already read can't be recalled.
@ -8,12 +8,12 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
return;
};
let Some(dest) = db.resolve_account(target).map(str::to_string) else {
ctx.notice(me, from.uid, format!("\x02{target}\x02 isn't registered."));
ctx.notice(me, from.uid, t!(ctx, "\x02{target}\x02 isn't registered.", target = target));
return;
};
if db.memo_cancel(&dest, account) {
ctx.notice(me, from.uid, format!("Your last unread memo to \x02{target}\x02 has been cancelled."));
ctx.notice(me, from.uid, t!(ctx, "Your last unread memo to \x02{target}\x02 has been cancelled.", target = target));
} else {
ctx.notice(me, from.uid, format!("You have no unread memo to \x02{target}\x02 to cancel."));
ctx.notice(me, from.uid, t!(ctx, "You have no unread memo to \x02{target}\x02 to cancel.", target = target));
}
}

View file

@ -1,4 +1,4 @@
use echo_api::{human_time, Sender, ServiceCtx, Store};
use echo_api::{human_time, t, Sender, ServiceCtx, Store};
// CHECK <nick>: has the last memo you sent to <nick> been read yet?
pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
@ -7,12 +7,12 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
return;
};
let Some(dest) = db.resolve_account(target).map(str::to_string) else {
ctx.notice(me, from.uid, format!("\x02{target}\x02 isn't registered."));
ctx.notice(me, from.uid, t!(ctx, "\x02{target}\x02 isn't registered.", target = target));
return;
};
match db.memo_check(&dest, account) {
Some((true, ts)) => ctx.notice(me, from.uid, format!("Your last memo to \x02{target}\x02 (sent {}) has been \x02read\x02.", human_time(ts))),
Some((false, ts)) => ctx.notice(me, from.uid, format!("Your last memo to \x02{target}\x02 (sent {}) has \x02not\x02 been read yet.", human_time(ts))),
None => ctx.notice(me, from.uid, format!("You have no memo on record to \x02{target}\x02.")),
Some((true, ts)) => ctx.notice(me, from.uid, t!(ctx, "Your last memo to \x02{target}\x02 (sent {when}) has been \x02read\x02.", target = target, when = human_time(ts))),
Some((false, ts)) => ctx.notice(me, from.uid, t!(ctx, "Your last memo to \x02{target}\x02 (sent {when}) has \x02not\x02 been read yet.", target = target, when = human_time(ts))),
None => ctx.notice(me, from.uid, t!(ctx, "You have no memo on record to \x02{target}\x02.", target = target)),
}
}

View file

@ -1,4 +1,4 @@
use echo_api::{Sender, ServiceCtx, Store};
use echo_api::{t, Sender, ServiceCtx, Store};
// DEL <num>|ALL: remove a memo (or the whole mailbox).
pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
@ -9,7 +9,7 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
for i in (0..count).rev() {
db.memo_del(account, i);
}
ctx.notice(me, from.uid, format!("Deleted all \x02{count}\x02 memo(s)."));
ctx.notice(me, from.uid, t!(ctx, "Deleted all \x02{count}\x02 memo(s).", count = count));
}
Some(numstr) => {
let Some(n) = numstr.parse::<usize>().ok().filter(|n| *n >= 1) else {
@ -17,9 +17,9 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
return;
};
if db.memo_del(account, n - 1) {
ctx.notice(me, from.uid, format!("Memo #\x02{n}\x02 deleted."));
ctx.notice(me, from.uid, t!(ctx, "Memo #\x02{n}\x02 deleted.", n = n));
} else {
ctx.notice(me, from.uid, format!("You have no memo #\x02{n}\x02."));
ctx.notice(me, from.uid, t!(ctx, "You have no memo #\x02{n}\x02.", n = n));
}
}
None => ctx.notice(me, from.uid, "Syntax: DEL <num>|ALL"),

View file

@ -1,4 +1,4 @@
use echo_api::{Sender, ServiceCtx, Store};
use echo_api::{t, Sender, ServiceCtx, Store};
// IGNORE ADD <nick> | DEL <nick> | LIST: manage your memo-ignore list. Memos
// from an ignored account are silently dropped.
@ -14,13 +14,13 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
// bound — mirrors AJOIN/CERT; unthrottled for identified users otherwise.
const MAX_IGNORE: usize = 50;
if db.memo_ignores(account).len() >= MAX_IGNORE {
ctx.notice(me, from.uid, format!("Your memo-ignore list is full (max {MAX_IGNORE})."));
ctx.notice(me, from.uid, t!(ctx, "Your memo-ignore list is full (max {max}).", max = MAX_IGNORE));
return;
}
if db.memo_ignore_add(account, &target) {
ctx.notice(me, from.uid, format!("Now ignoring memos from \x02{target}\x02."));
ctx.notice(me, from.uid, t!(ctx, "Now ignoring memos from \x02{target}\x02.", target = target));
} else {
ctx.notice(me, from.uid, format!("You're already ignoring \x02{target}\x02."));
ctx.notice(me, from.uid, t!(ctx, "You're already ignoring \x02{target}\x02.", target = target));
}
}
Some("DEL") | Some("REMOVE") => {
@ -30,9 +30,9 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
};
let target = db.resolve_account(nick).map(str::to_string).unwrap_or_else(|| nick.to_string());
if db.memo_ignore_del(account, &target) {
ctx.notice(me, from.uid, format!("No longer ignoring \x02{target}\x02."));
ctx.notice(me, from.uid, t!(ctx, "No longer ignoring \x02{target}\x02.", target = target));
} else {
ctx.notice(me, from.uid, format!("You weren't ignoring \x02{target}\x02."));
ctx.notice(me, from.uid, t!(ctx, "You weren't ignoring \x02{target}\x02.", target = target));
}
}
Some("LIST") | None => {
@ -40,7 +40,7 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
if list.is_empty() {
ctx.notice(me, from.uid, "Your memo-ignore list is empty.");
} else {
ctx.notice(me, from.uid, format!("You're ignoring memos from: {}", list.join(", ")));
ctx.notice(me, from.uid, t!(ctx, "You're ignoring memos from: {names}", names = list.join(", ")));
}
}
_ => ctx.notice(me, from.uid, "Syntax: IGNORE ADD <nick> | DEL <nick> | LIST"),

View file

@ -1,4 +1,4 @@
use echo_api::{Sender, ServiceCtx, Store};
use echo_api::{t, Sender, ServiceCtx, Store};
// INFO: a summary of your mailbox (total, unread, capacity).
pub fn handle(me: &str, from: &Sender, account: &str, ctx: &mut ServiceCtx, db: &mut dyn Store) {
@ -7,6 +7,6 @@ pub fn handle(me: &str, from: &Sender, account: &str, ctx: &mut ServiceCtx, db:
ctx.notice(
me,
from.uid,
format!("You have \x02{total}\x02 memo(s), \x02{unread}\x02 unread, of a maximum \x02{}\x02.", super::MAX_MEMOS),
t!(ctx, "You have \x02{total}\x02 memo(s), \x02{unread}\x02 unread, of a maximum \x02{max}\x02.", total = total, unread = unread, max = super::MAX_MEMOS),
);
}

View file

@ -4,7 +4,7 @@
//! account data. `lib.rs` holds the dispatcher; each command lives in its own
//! file, matching NickServ/ChanServ.
use echo_api::{HelpEntry, NetView, Sender, Service, ServiceCtx, Store};
use echo_api::{t, HelpEntry, NetView, Sender, Service, ServiceCtx, Store};
#[path = "send.rs"]
mod send;
@ -93,7 +93,7 @@ impl Service for MemoServ {
Some("STAFF") => staff::handle(me, from, account, args, ctx, net, db),
Some("IGNORE") => ignore::handle(me, from, account, args, ctx, db),
Some("SET") => set::handle(me, from, account, args, ctx, db),
Some(other) => ctx.notice(me, from.uid, format!("I don't know the command \x02{other}\x02. Try \x02HELP\x02.")),
Some(other) => ctx.notice(me, from.uid, t!(ctx, "I don't know the command \x02{other}\x02. Try \x02HELP\x02.", other = other)),
None => {}
}
}

View file

@ -1,4 +1,4 @@
use echo_api::{human_time, Sender, ServiceCtx, Store};
use echo_api::{human_time, t, Sender, ServiceCtx, Store};
// LIST: show every memo with a one-line preview; \x02*\x02 marks unread.
pub fn handle(me: &str, from: &Sender, account: &str, ctx: &mut ServiceCtx, db: &dyn Store) {
@ -8,10 +8,10 @@ pub fn handle(me: &str, from: &Sender, account: &str, ctx: &mut ServiceCtx, db:
return;
}
let unread = memos.iter().filter(|m| !m.read).count();
ctx.notice(me, from.uid, format!("Your memos ({} total, {unread} new). \x02*\x02 marks unread:", memos.len()));
ctx.notice(me, from.uid, t!(ctx, "Your memos ({total} total, {unread} new). \x02*\x02 marks unread:", total = memos.len(), unread = unread));
for (i, m) in memos.iter().enumerate() {
let flag = if m.read { ' ' } else { '*' };
ctx.notice(me, from.uid, format!(" {}{flag} from \x02{}\x02 ({}): {}", i + 1, m.from, human_time(m.ts), preview(&m.text)));
ctx.notice(me, from.uid, t!(ctx, " {num}{flag} from \x02{from}\x02 ({when}): {preview}", num = i + 1, flag = flag, from = m.from, when = human_time(m.ts), preview = preview(&m.text)));
}
}

View file

@ -1,4 +1,4 @@
use echo_api::{human_time, MemoView, Sender, ServiceCtx, Store};
use echo_api::{human_time, t, MemoView, Sender, ServiceCtx, Store};
// READ <num>|NEW|ALL: display memos and mark them read.
pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
@ -33,7 +33,7 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
show(me, from, n - 1, &m, ctx);
send_receipt(account, &m, db);
}
None => ctx.notice(me, from.uid, format!("You have no memo #\x02{n}\x02.")),
None => ctx.notice(me, from.uid, t!(ctx, "You have no memo #\x02{n}\x02.", n = n)),
}
}
None => ctx.notice(me, from.uid, "Syntax: READ <num>|NEW|ALL"),
@ -41,8 +41,8 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
}
fn show(me: &str, from: &Sender, index: usize, m: &MemoView, ctx: &mut ServiceCtx) {
ctx.notice(me, from.uid, format!("Memo #\x02{}\x02 from \x02{}\x02 ({}):", index + 1, m.from, human_time(m.ts)));
ctx.notice(me, from.uid, format!(" {}", m.text));
ctx.notice(me, from.uid, t!(ctx, "Memo #\x02{num}\x02 from \x02{from}\x02 ({when}):", num = index + 1, from = m.from, when = human_time(m.ts)));
ctx.notice(me, from.uid, t!(ctx, " {text}", text = m.text));
}
// If this was an unread RSEND memo, memo the sender that it's now been read.

View file

@ -1,4 +1,4 @@
use echo_api::{Sender, ServiceCtx, Store};
use echo_api::{t, Sender, ServiceCtx, Store};
use super::MAX_MEMOS;
@ -7,28 +7,28 @@ use super::MAX_MEMOS;
pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store, receipt: bool) {
let cmd = if receipt { "RSEND" } else { "SEND" };
if args.len() < 3 {
ctx.notice(me, from.uid, format!("Syntax: {cmd} <nick> <text>"));
ctx.notice(me, from.uid, t!(ctx, "Syntax: {cmd} <nick> <text>", cmd = cmd));
return;
}
let target = args[1];
let text = args[2..].join(" ");
let Some(dest) = db.resolve_account(target).map(str::to_string) else {
ctx.notice(me, from.uid, format!("\x02{target}\x02 isn't registered."));
ctx.notice(me, from.uid, t!(ctx, "\x02{target}\x02 isn't registered.", target = target));
return;
};
let limit = db.memo_limit_of(&dest).unwrap_or(MAX_MEMOS as u32) as usize;
if db.memo_list(&dest).len() >= limit {
ctx.notice(me, from.uid, format!("\x02{target}\x02's mailbox is full — they'll need to clear some memos first."));
ctx.notice(me, from.uid, t!(ctx, "\x02{target}\x02's mailbox is full — they'll need to clear some memos first.", target = target));
return;
}
// If the recipient is ignoring the sender, drop it silently — the sender is
// told it was sent, so the ignore isn't revealed.
if db.memo_is_ignored(&dest, account) {
ctx.notice(me, from.uid, format!("Memo sent to \x02{target}\x02."));
ctx.notice(me, from.uid, t!(ctx, "Memo sent to \x02{target}\x02.", target = target));
return;
}
match db.memo_send(&dest, account, &text, receipt) {
Ok(()) => ctx.notice(me, from.uid, format!("Memo sent to \x02{target}\x02.")),
Ok(()) => ctx.notice(me, from.uid, t!(ctx, "Memo sent to \x02{target}\x02.", target = target)),
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
}
}

View file

@ -1,4 +1,4 @@
use echo_api::{Priv, Sender, ServiceCtx, Store};
use echo_api::{t, Priv, Sender, ServiceCtx, Store};
// SENDALL <text>: leave a memo on every registered account. Admin-only, for
// network-wide announcements that persist until read.
@ -20,5 +20,5 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
sent += 1;
}
}
ctx.notice(me, from.uid, format!("Memo sent to \x02{sent}\x02 account(s)."));
ctx.notice(me, from.uid, t!(ctx, "Memo sent to \x02{sent}\x02 account(s).", sent = sent));
}

View file

@ -1,4 +1,4 @@
use echo_api::{Sender, ServiceCtx, Store};
use echo_api::{t, Sender, ServiceCtx, Store};
// SET NOTIFY {ON|OFF} | SET LIMIT <n>|NONE: your MemoServ preferences.
pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
@ -13,7 +13,7 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
}
};
db.set_memo_notify(account, on);
ctx.notice(me, from.uid, format!("New-memo notification is now \x02{}\x02.", if on { "on" } else { "off" }));
ctx.notice(me, from.uid, t!(ctx, "New-memo notification is now \x02{state}\x02.", state = if on { "on" } else { "off" }));
}
Some("LIMIT") => {
let limit = match args.get(2) {
@ -22,15 +22,15 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
Some(&n) => match n.parse::<u32>() {
Ok(v) if v <= super::MAX_MEMOS as u32 => Some(v),
_ => {
ctx.notice(me, from.uid, format!("The limit must be a number from 0 to {}, or NONE.", super::MAX_MEMOS));
ctx.notice(me, from.uid, t!(ctx, "The limit must be a number from 0 to {max}, or NONE.", max = super::MAX_MEMOS));
return;
}
},
};
db.set_memo_limit(account, limit);
match limit {
Some(v) => ctx.notice(me, from.uid, format!("Your mailbox limit is now \x02{v}\x02.")),
None => ctx.notice(me, from.uid, format!("Your mailbox limit is now the network default (\x02{}\x02).", super::MAX_MEMOS)),
Some(v) => ctx.notice(me, from.uid, t!(ctx, "Your mailbox limit is now \x02{v}\x02.", v = v)),
None => ctx.notice(me, from.uid, t!(ctx, "Your mailbox limit is now the network default (\x02{max}\x02).", max = super::MAX_MEMOS)),
}
}
_ => ctx.notice(me, from.uid, "Syntax: SET NOTIFY {ON|OFF} | SET LIMIT <n>|NONE"),

View file

@ -1,4 +1,4 @@
use echo_api::{NetView, Priv, Sender, ServiceCtx, Store};
use echo_api::{t, NetView, Priv, Sender, ServiceCtx, Store};
// STAFF <text>: leave a memo on every operator's account. Admin-only, for
// notes to the staff team that persist until read. Recipients are the union of
@ -29,5 +29,5 @@ pub fn handle(me: &str, from: &Sender, account: &str, args: &[&str], ctx: &mut S
sent += 1;
}
}
ctx.notice(me, from.uid, format!("Memo sent to \x02{sent}\x02 operator(s)."));
ctx.notice(me, from.uid, t!(ctx, "Memo sent to \x02{sent}\x02 operator(s).", sent = sent));
}