Add searching for players by name or discriminator
This commit is contained in:
parent
0c9d85666c
commit
f7fa4c2085
|
@ -327,6 +327,42 @@ pub fn get_player(connection: &Connection, player: PlayerId) -> sqlite::Result<P
|
|||
})
|
||||
}
|
||||
|
||||
pub fn get_player_from_discrim(
|
||||
connection: &Connection,
|
||||
discrim: &str,
|
||||
) -> sqlite::Result<PlayerData> {
|
||||
let query = "SELECT id, name, prefix FROM players WHERE discrim = ?";
|
||||
|
||||
let mut statement = connection.prepare(&query)?;
|
||||
statement.bind((1, discrim))?;
|
||||
statement.next()?;
|
||||
Ok(PlayerData {
|
||||
id: PlayerId(statement.read::<i64, _>("id")? as u64),
|
||||
name: statement.read::<String, _>("name")?,
|
||||
prefix: statement.read::<Option<String>, _>("prefix")?,
|
||||
discrim: discrim.to_owned(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn match_player_name(connection: &Connection, name: &str) -> sqlite::Result<Vec<PlayerData>> {
|
||||
let query = "SELECT * FROM players WHERE name LIKE ?";
|
||||
|
||||
connection
|
||||
.prepare(&query)?
|
||||
.into_iter()
|
||||
.bind((1, &format!("%{}%", name)[..]))?
|
||||
.map(|r| {
|
||||
let r_ = r?;
|
||||
Ok(PlayerData {
|
||||
id: PlayerId(r_.read::<i64, _>("id") as u64),
|
||||
name: r_.read::<&str, _>("name").to_owned(),
|
||||
prefix: r_.read::<Option<&str>, _>("prefix").map(|x| x.to_owned()),
|
||||
discrim: r_.read::<&str, _>("discrim").to_owned(),
|
||||
})
|
||||
})
|
||||
.try_collect()
|
||||
}
|
||||
|
||||
pub fn get_player_rating_data(
|
||||
connection: &Connection,
|
||||
dataset: &str,
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -80,13 +80,7 @@ created if it does not already exist."
|
|||
Player {
|
||||
#[command(subcommand)]
|
||||
subcommand: PlayerSC,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
value_name = "DATASET",
|
||||
global = true,
|
||||
help = "The dataset to access"
|
||||
)]
|
||||
#[arg(short, long, global = true, help = "The dataset to access")]
|
||||
dataset: Option<String>,
|
||||
},
|
||||
}
|
||||
|
@ -465,17 +459,16 @@ fn player_info(dataset: Option<String>, player: String) {
|
|||
let connection =
|
||||
open_datasets(&config_dir).unwrap_or_else(|_| error("Could not open datasets file", 2));
|
||||
|
||||
let player_id = PlayerId(player.parse::<u64>().unwrap());
|
||||
|
||||
let PlayerData {
|
||||
id: _,
|
||||
id,
|
||||
name,
|
||||
prefix,
|
||||
discrim,
|
||||
} = get_player(&connection, player_id).unwrap();
|
||||
} = get_player_from_input(&connection, player)
|
||||
.unwrap_or_else(|_| error("Could not find player", 1));
|
||||
|
||||
let (deviation, volatility, last_played) =
|
||||
get_player_rating_data(&connection, &dataset, player_id).unwrap();
|
||||
let (deviation, volatility, _) = get_player_rating_data(&connection, &dataset, id)
|
||||
.unwrap_or_else(|_| error("Could not find player", 1));
|
||||
|
||||
println!();
|
||||
if let Some(pre) = prefix {
|
||||
|
@ -487,8 +480,8 @@ fn player_info(dataset: Option<String>, player: String) {
|
|||
name, discrim
|
||||
);
|
||||
|
||||
println!("\n\x1b[1mID:\x1b[0m {}", player_id.0);
|
||||
println!("\x1b[1mDeviation:\x1b[0m {}", deviation);
|
||||
println!("\x1b[1mID:\x1b[0m {}", id.0);
|
||||
println!("\n\x1b[1mDeviation:\x1b[0m {}", deviation);
|
||||
println!("\x1b[1mVolatility:\x1b[0m {}", volatility);
|
||||
}
|
||||
|
||||
|
|
60
src/util.rs
60
src/util.rs
|
@ -1,6 +1,10 @@
|
|||
use sqlite::*;
|
||||
use std::io::{self, Write};
|
||||
use std::process::exit;
|
||||
|
||||
use crate::database::*;
|
||||
use crate::queries::{PlayerData, PlayerId};
|
||||
|
||||
pub const SECS_IN_HR: u64 = 3600;
|
||||
pub const SECS_IN_DAY: u64 = SECS_IN_HR * 24;
|
||||
pub const SECS_IN_WEEK: u64 = SECS_IN_DAY * 7;
|
||||
|
@ -25,3 +29,59 @@ pub fn read_string() -> String {
|
|||
.unwrap_or_else(|_| error("Could not read from stdin", 2));
|
||||
line.trim().to_owned()
|
||||
}
|
||||
|
||||
pub enum PlayerInput {
|
||||
Id(PlayerId),
|
||||
Discrim(String),
|
||||
Name(String),
|
||||
}
|
||||
|
||||
pub fn parse_player_input(input: String) -> PlayerInput {
|
||||
if let Ok(id) = input.parse::<u64>() {
|
||||
PlayerInput::Id(PlayerId(id))
|
||||
} else if input.chars().all(|c| c.is_ascii_hexdigit()) {
|
||||
PlayerInput::Discrim(input)
|
||||
} else {
|
||||
PlayerInput::Name(input)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_player_from_input(connection: &Connection, input: String) -> sqlite::Result<PlayerData> {
|
||||
match parse_player_input(input) {
|
||||
PlayerInput::Id(id) => get_player(connection, id),
|
||||
PlayerInput::Discrim(discrim) => get_player_from_discrim(connection, &discrim),
|
||||
PlayerInput::Name(name) => {
|
||||
let players = match_player_name(connection, &name)?;
|
||||
|
||||
if players.is_empty() {
|
||||
error(&format!("Player {:?} not found", name), 1);
|
||||
} else if players.len() == 1 {
|
||||
Ok(players.into_iter().next().unwrap())
|
||||
} else {
|
||||
println!("\nInput {:?} matches more than one player:\n", name);
|
||||
|
||||
for (i, player) in players.iter().enumerate() {
|
||||
print!("{} - ", i);
|
||||
if let Some(pre) = player.prefix.clone() {
|
||||
print!("\x1b[2m{}\x1b[22m ", pre);
|
||||
}
|
||||
println!(
|
||||
"\x1b[4m\x1b]8;;https://www.start.gg/user/{1}\x1b\\\
|
||||
\x1b[1m{0}\x1b[22m\x1b]8;;\x1b\\\x1b[0m ({1})",
|
||||
player.name, player.discrim
|
||||
)
|
||||
}
|
||||
|
||||
print!("\nPlayer (0-{}): ", players.len() - 1);
|
||||
let index = read_string()
|
||||
.parse::<usize>()
|
||||
.unwrap_or_else(|_| error("Not an integer", 1));
|
||||
if index >= players.len() {
|
||||
error("Out of range!", 1);
|
||||
}
|
||||
|
||||
Ok(players[index].clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue