use crate::atcoder;
use crate::browser;
use crate::workspace;
use crate::workspace::CurrentContext;
fn resolve_contest_id(
current: CurrentContext,
contest_id: Option<String>,
) -> anyhow::Result<String> {
match current {
CurrentContext::ProblemDir(ctx) => match contest_id {
Some(_) => anyhow::bail!("Cannot specify a contest ID from a problem directory."),
None => Ok(ctx.contest_id),
},
CurrentContext::ContestDir(ctx) => match contest_id {
Some(_) => anyhow::bail!("Cannot specify a contest ID from a contest directory."),
None => Ok(ctx.contest_id),
},
CurrentContext::Outside => match contest_id {
Some(id) => {
workspace::find_contest_dir_by_id(&id)?;
Ok(id)
}
None => anyhow::bail!("Specify a contest ID or run from a contest directory."),
},
}
}
fn build_url(contest_id: &str) -> String {
format!(
"{}/contests/{}/submissions/me",
atcoder::BASE_URL,
contest_id
)
}
pub fn execute(contest_id: Option<String>) -> anyhow::Result<()> {
let current = workspace::detect_current_context();
let contest_id = resolve_contest_id(current, contest_id)?;
let url = build_url(&contest_id);
browser::open(&url);
println!("{}", url);
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::workspace::{ContestContext, ProblemContext};
use std::path::PathBuf;
fn make_problem_context(contest_id: &str) -> ProblemContext {
ProblemContext {
contest_id: contest_id.to_string(),
problem_alphabet: "a".to_string(),
task_screen_name: format!("{}_a", contest_id),
problem_dir: PathBuf::from(format!("/tmp/{}/a", contest_id)),
problem_url: format!(
"https://atcoder.jp/contests/{}/tasks/{}_a",
contest_id, contest_id
),
}
}
fn make_contest_context(contest_id: &str) -> ContestContext {
ContestContext {
contest_id: contest_id.to_string(),
contest_dir: PathBuf::from(format!("/tmp/{}", contest_id)),
}
}
#[test]
fn test_resolve_contest_id_problem_dir() {
let ctx = CurrentContext::ProblemDir(make_problem_context("abc001"));
let id = resolve_contest_id(ctx, None).unwrap();
assert_eq!(id, "abc001");
}
#[test]
fn test_resolve_contest_id_problem_dir_with_id_error() {
let ctx = CurrentContext::ProblemDir(make_problem_context("abc001"));
assert!(resolve_contest_id(ctx, Some("abc002".to_string())).is_err());
}
#[test]
fn test_resolve_contest_id_contest_dir() {
let ctx = CurrentContext::ContestDir(make_contest_context("abc001"));
let id = resolve_contest_id(ctx, None).unwrap();
assert_eq!(id, "abc001");
}
#[test]
fn test_resolve_contest_id_contest_dir_with_id_error() {
let ctx = CurrentContext::ContestDir(make_contest_context("abc001"));
assert!(resolve_contest_id(ctx, Some("abc002".to_string())).is_err());
}
#[test]
fn test_resolve_contest_id_outside_no_id_error() {
let ctx = CurrentContext::Outside;
assert!(resolve_contest_id(ctx, None).is_err());
}
#[test]
fn test_build_url() {
assert_eq!(
build_url("abc001"),
"https://atcoder.jp/contests/abc001/submissions/me"
);
}
}