Move to SQLite (#13)

This commit is contained in:
Natsu Kagami 2021-06-19 22:36:17 +09:00 committed by GitHub
parent 750ddb7762
commit 1799b70bc1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 2122 additions and 394 deletions

View file

@ -78,7 +78,7 @@ async fn update_user(
.await?
.into_iter()
.next()
.ok_or(Error::msg("Not found"))?;
.ok_or_else(|| Error::msg("Not found"))?;
let rating_changes = info.rating_changes(&*client).await?;

View file

@ -31,12 +31,12 @@ pub fn user_embed<'a>(user: &User, e: &'a mut CreateEmbed) -> &'a mut CreateEmbe
.url(user.profile_url())
.description(format!(
"{}\n{}",
if name == "" {
if name.is_empty() {
"".to_owned()
} else {
format!("**{}**", name)
},
if place == "" {
if place.is_empty() {
"".to_owned()
} else {
format!("from **{}**", place)

View file

@ -77,11 +77,11 @@ impl ContestCache {
}
async fn get_from_list(&self, contest_id: u64) -> Result<Contest> {
let last_updated = self.all_list.read().await.1.clone();
let last_updated = self.all_list.read().await.1;
if Instant::now() - last_updated > std::time::Duration::from_secs(60 * 60) {
// We update at most once an hour.
*self.all_list.write().await =
(Contest::list(&*self.http, true).await?, Instant::now());
let mut v = self.all_list.write().await;
*v = (Contest::list(&*self.http, true).await?, Instant::now());
}
self.all_list
.read()
@ -194,7 +194,7 @@ fn print_info_message<'a>(
problems
.as_ref()
.map(|v| format!(" | **{}** problems", v.len()))
.unwrap_or("".to_owned()),
.unwrap_or_else(|| "".to_owned()),
)
.push(
contest
@ -203,7 +203,7 @@ fn print_info_message<'a>(
.map(|v| {
format!(" | from **{}**", Utc.timestamp(*v as i64, 0).to_rfc2822())
})
.unwrap_or("".to_owned()),
.unwrap_or_else(|| "".to_owned()),
)
.push(format!(" | duration **{}**", duration));
if let Some(p) = &contest.prepared_by {
@ -218,20 +218,21 @@ fn print_info_message<'a>(
e.description(m.build())
}
#[allow(clippy::needless_lifetimes)] // Doesn't really work
async fn parse_capture<'a>(
contest_cache: &ContestCache,
cap: Captures<'a>,
) -> Result<(ContestOrProblem, &'a str), CommandError> {
let contest_id: u64 = cap
.name("contest")
.ok_or(CommandError::from("Contest not captured"))?
.ok_or_else(|| CommandError::from("Contest not captured"))?
.as_str()
.parse()?;
let (contest, problems) = contest_cache.get(contest_id).await?;
match cap.name("problem") {
Some(p) => {
for problem in problems.ok_or(CommandError::from("Contest hasn't started"))? {
if &problem.index == p.as_str() {
for problem in problems.ok_or_else(|| CommandError::from("Contest hasn't started"))? {
if problem.index == p.as_str() {
return Ok((
ContestOrProblem::Problem(problem),
cap.get(0).unwrap().as_str(),

View file

@ -56,7 +56,7 @@ pub async fn profile(ctx: &Context, m: &Message, mut args: Args) -> CommandResul
let data = ctx.data.read().await;
let handle = args
.single::<UsernameArg>()
.unwrap_or(UsernameArg::mention(m.author.id));
.unwrap_or_else(|_| UsernameArg::mention(m.author.id));
let http = data.get::<CFClient>().unwrap();
let handle = match handle {
@ -142,9 +142,7 @@ pub async fn ranks(ctx: &Context, m: &Message) -> CommandResult {
let everyone = {
let db = CfSavedUsers::open(&*data);
let db = db.borrow()?;
db.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect::<Vec<_>>()
db.iter().map(|(k, v)| (*k, v.clone())).collect::<Vec<_>>()
};
let guild = m.guild_id.expect("Guild-only command");
let mut ranks = everyone
@ -216,7 +214,7 @@ pub async fn ranks(ctx: &Context, m: &Message) -> CommandResult {
format!("#{}", id),
cfu.rating
.map(|v| v.to_string())
.unwrap_or("----".to_owned()),
.unwrap_or_else(|| "----".to_owned()),
cfu.handle,
mem.distinct(),
hw = handle_width,
@ -264,7 +262,7 @@ pub async fn contestranks(ctx: &Context, m: &Message, mut args: Args) -> Command
.map(|v| v.map(|v| (cf_user.handle, v)))
})
.collect::<stream::FuturesUnordered<_>>()
.filter_map(|v| future::ready(v))
.filter_map(future::ready)
.collect::<HashMap<_, _>>()
.await;
let http = data.get::<CFClient>().unwrap();
@ -394,7 +392,7 @@ pub(crate) async fn contest_rank_table(
table.push(" | ");
if p.points > 0.0 {
table.push(format!("{:^4.0}", p.points));
} else if let Some(_) = p.best_submission_time_seconds {
} else if p.best_submission_time_seconds.is_some() {
table.push(format!("{:^4}", "?"));
} else if p.rejected_attempt_count > 0 {
table.push(format!("{:^4}", format!("-{}", p.rejected_attempt_count)));

View file

@ -51,7 +51,7 @@ pub async fn watch_contest(
}
})
.collect::<stream::FuturesUnordered<_>>()
.filter_map(|v| future::ready(v))
.filter_map(future::ready)
.collect()
.await;
@ -323,7 +323,7 @@ enum Change {
fn analyze_change(contest: &Contest, old: &ProblemResult, new: &ProblemResult) -> Option<Change> {
use Change::*;
if old.points == new.points {
if (old.points - new.points).abs() < 0.001 {
if new.rejected_attempt_count > old.rejected_attempt_count {
if new.result_type == ProblemResultType::Preliminary {
return Some(Attempted);
@ -335,25 +335,23 @@ fn analyze_change(contest: &Contest, old: &ProblemResult, new: &ProblemResult) -
return Some(Accepted);
}
None
} else {
if new.points == 0.0 {
if new.result_type == ProblemResultType::Preliminary {
if contest.phase == ContestPhase::Coding {
Some(Hacked)
} else {
None // Just changes to In Queue...
}
} else if new.points == 0.0 {
if new.result_type == ProblemResultType::Preliminary {
if contest.phase == ContestPhase::Coding {
Some(Hacked)
} else {
Some(TestFailed)
}
} else if new.points > old.points {
if new.result_type == ProblemResultType::Preliminary {
Some(PretestsPassed)
} else {
Some(Accepted)
None // Just changes to In Queue...
}
} else {
Some(PretestsPassed)
Some(TestFailed)
}
} else if new.points > old.points {
if new.result_type == ProblemResultType::Preliminary {
Some(PretestsPassed)
} else {
Some(Accepted)
}
} else {
Some(PretestsPassed)
}
}