From adc33076f3024782f93ace0d21c469a761478236 Mon Sep 17 00:00:00 2001 From: Natsu Kagami Date: Sun, 9 Feb 2020 14:13:19 -0500 Subject: [PATCH] Generalize UsernameArg --- youmubot-osu/src/discord/mod.rs | 64 +++++++++++---------------------- youmubot-prelude/src/args.rs | 29 +++++++++++++++ youmubot-prelude/src/lib.rs | 2 +- 3 files changed, 51 insertions(+), 44 deletions(-) diff --git a/youmubot-osu/src/discord/mod.rs b/youmubot-osu/src/discord/mod.rs index 70dadea..8bd76e2 100644 --- a/youmubot-osu/src/discord/mod.rs +++ b/youmubot-osu/src/discord/mod.rs @@ -180,39 +180,24 @@ impl FromStr for ModeArg { } } -enum UsernameArg { - Tagged(UserId), - Raw(String), +fn to_user_id_query( + s: Option, + data: &ShareMap, + msg: &Message, +) -> Result { + let id = match s { + Some(UsernameArg::Raw(s)) => return Ok(UserID::Auto(s)), + Some(UsernameArg::Tagged(r)) => r, + None => msg.author.id, + }; + + let db = OsuSavedUsers::open(data); + let db = db.borrow()?; + db.get(&id) + .cloned() + .map(|u| UserID::ID(u.id)) + .ok_or(Error::from("No saved account found")) } - -impl UsernameArg { - fn to_user_id_query(s: Option, data: &ShareMap, msg: &Message) -> Result { - let id = match s { - Some(UsernameArg::Raw(s)) => return Ok(UserID::Auto(s)), - Some(UsernameArg::Tagged(r)) => r, - None => msg.author.id, - }; - - let db = OsuSavedUsers::open(data); - let db = db.borrow()?; - db.get(&id) - .cloned() - .map(|u| UserID::ID(u.id)) - .ok_or(Error::from("No saved account found")) - } -} - -impl FromStr for UsernameArg { - type Err = String; - fn from_str(s: &str) -> Result { - match s.parse::() { - 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); impl FromStr for Nth { @@ -235,8 +220,7 @@ impl FromStr for Nth { pub fn recent(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { let nth = args.single::().unwrap_or(Nth(1)).0.min(50).max(1); let mode = args.single::().unwrap_or(ModeArg(Mode::Std)).0; - let user = - UsernameArg::to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; + let user = to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; let osu = ctx.data.get_cloned::(); let user = osu @@ -308,11 +292,7 @@ pub fn check(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult Some(bm) => { let b = &bm.0; let m = bm.1; - let user = UsernameArg::to_user_id_query( - args.single::().ok(), - &*ctx.data.read(), - msg, - )?; + let user = to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; let osu = ctx.data.get_cloned::(); @@ -348,8 +328,7 @@ pub fn top(ctx: &mut Context, msg: &Message, mut args: Args) -> CommandResult { .map(|ModeArg(t)| t) .unwrap_or(Mode::Std); - let user = - UsernameArg::to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; + let user = to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; let osu = ctx.data.get_cloned::(); 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 { - let user = - UsernameArg::to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; + let user = to_user_id_query(args.single::().ok(), &*ctx.data.read(), msg)?; let osu = ctx.data.get_cloned::(); let user = osu.user(user, |f| f.mode(mode))?; match user { diff --git a/youmubot-prelude/src/args.rs b/youmubot-prelude/src/args.rs index d2e39b0..b6b96f9 100644 --- a/youmubot-prelude/src/args.rs +++ b/youmubot-prelude/src/args.rs @@ -1,4 +1,5 @@ pub use duration::Duration; +pub use username_arg::UsernameArg; mod duration { 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 { + match s.parse::() { + 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>(v: T) -> Self { + Self::Tagged(v.into()) + } + } +} diff --git a/youmubot-prelude/src/lib.rs b/youmubot-prelude/src/lib.rs index 77a31a1..cf05cb0 100644 --- a/youmubot-prelude/src/lib.rs +++ b/youmubot-prelude/src/lib.rs @@ -8,7 +8,7 @@ pub mod reaction_watch; pub mod setup; pub use announcer::Announcer; -pub use args::Duration; +pub use args::{Duration, UsernameArg}; pub use pagination::Pagination; pub use reaction_watch::{ReactionHandler, ReactionWatcher};