Generalize UsernameArg

This commit is contained in:
Natsu Kagami 2020-02-09 14:13:19 -05:00
parent 5b64d1e535
commit adc33076f3
Signed by: nki
GPG key ID: 73376E117CD20735
3 changed files with 51 additions and 44 deletions

View file

@ -180,13 +180,11 @@ impl FromStr for ModeArg {
} }
} }
enum UsernameArg { fn to_user_id_query(
Tagged(UserId), s: Option<UsernameArg>,
Raw(String), data: &ShareMap,
} msg: &Message,
) -> Result<UserID, Error> {
impl UsernameArg {
fn to_user_id_query(s: Option<Self>, data: &ShareMap, msg: &Message) -> Result<UserID, Error> {
let id = match s { let id = match s {
Some(UsernameArg::Raw(s)) => return Ok(UserID::Auto(s)), Some(UsernameArg::Raw(s)) => return Ok(UserID::Auto(s)),
Some(UsernameArg::Tagged(r)) => r, Some(UsernameArg::Tagged(r)) => r,
@ -200,19 +198,6 @@ impl UsernameArg {
.map(|u| UserID::ID(u.id)) .map(|u| UserID::ID(u.id))
.ok_or(Error::from("No saved account found")) .ok_or(Error::from("No saved account found"))
} }
}
impl FromStr for UsernameArg {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.parse::<UserId>() {
Ok(v) => Ok(UsernameArg::Tagged(v)),
Err(_) if !s.is_empty() => Ok(UsernameArg::Raw(s.to_owned())),
Err(_) => Err("username arg cannot be empty".to_owned()),
}
}
}
struct Nth(u8); struct Nth(u8);
impl FromStr for Nth { impl FromStr for Nth {
@ -235,8 +220,7 @@ impl FromStr for Nth {
pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
let nth = args.single::<Nth>().unwrap_or(Nth(1)).0.min(50).max(1); let nth = args.single::<Nth>().unwrap_or(Nth(1)).0.min(50).max(1);
let mode = args.single::<ModeArg>().unwrap_or(ModeArg(Mode::Std)).0; let mode = args.single::<ModeArg>().unwrap_or(ModeArg(Mode::Std)).0;
let user = let user = to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
UsernameArg::to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
let osu = ctx.data.get_cloned::<OsuClient>(); let osu = ctx.data.get_cloned::<OsuClient>();
let user = osu let user = osu
@ -308,11 +292,7 @@ pub fn check(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult
Some(bm) => { Some(bm) => {
let b = &bm.0; let b = &bm.0;
let m = bm.1; let m = bm.1;
let user = UsernameArg::to_user_id_query( let user = to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
args.single::<UsernameArg>().ok(),
&*ctx.data.read(),
msg,
)?;
let osu = ctx.data.get_cloned::<OsuClient>(); let osu = ctx.data.get_cloned::<OsuClient>();
@ -348,8 +328,7 @@ pub fn top(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
.map(|ModeArg(t)| t) .map(|ModeArg(t)| t)
.unwrap_or(Mode::Std); .unwrap_or(Mode::Std);
let user = let user = to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
UsernameArg::to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
let osu = ctx.data.get_cloned::<OsuClient>(); let osu = ctx.data.get_cloned::<OsuClient>();
let user = osu let user = osu
@ -387,8 +366,7 @@ pub fn top(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult {
} }
fn get_user(ctx: &mut Context, msg: &Message, mut args: Args, mode: Mode) -> CommandResult { fn get_user(ctx: &mut Context, msg: &Message, mut args: Args, mode: Mode) -> CommandResult {
let user = let user = to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
UsernameArg::to_user_id_query(args.single::<UsernameArg>().ok(), &*ctx.data.read(), msg)?;
let osu = ctx.data.get_cloned::<OsuClient>(); let osu = ctx.data.get_cloned::<OsuClient>();
let user = osu.user(user, |f| f.mode(mode))?; let user = osu.user(user, |f| f.mode(mode))?;
match user { match user {

View file

@ -1,4 +1,5 @@
pub use duration::Duration; pub use duration::Duration;
pub use username_arg::UsernameArg;
mod duration { mod duration {
use std::fmt; use std::fmt;
@ -169,3 +170,31 @@ mod duration {
} }
} }
} }
mod username_arg {
use serenity::model::id::UserId;
use std::str::FromStr;
/// An argument that can be either a tagged user, or a raw string.
pub enum UsernameArg {
Tagged(UserId),
Raw(String),
}
impl FromStr for UsernameArg {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.parse::<UserId>() {
Ok(v) => Ok(UsernameArg::Tagged(v)),
Err(_) if !s.is_empty() => Ok(UsernameArg::Raw(s.to_owned())),
Err(_) => Err("username arg cannot be empty".to_owned()),
}
}
}
impl UsernameArg {
/// Mention yourself.
pub fn mention<T: Into<UserId>>(v: T) -> Self {
Self::Tagged(v.into())
}
}
}

View file

@ -8,7 +8,7 @@ pub mod reaction_watch;
pub mod setup; pub mod setup;
pub use announcer::Announcer; pub use announcer::Announcer;
pub use args::Duration; pub use args::{Duration, UsernameArg};
pub use pagination::Pagination; pub use pagination::Pagination;
pub use reaction_watch::{ReactionHandler, ReactionWatcher}; pub use reaction_watch::{ReactionHandler, ReactionWatcher};