1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
mod commands;
mod fs;
mod process;
mod project;
pub mod shell;
mod testing;
mod web;

use crate::{
    commands::{
        init::OptCompeteInit, login::OptCompeteLogin, participate::OptCompeteParticipate,
        retrieve_testcases::OptCompeteRetrieveTestcases, submit::OptCompeteSubmit,
        test::OptCompeteTest, watch_submissions::OptCompeteWatchSubmissions,
    },
    shell::Shell,
};
use semver::Version;
use std::path::PathBuf;
use structopt::{clap::AppSettings, StructOpt};

static ATCODER_RUST_VERSION: Version = semver(1, 42, 0);
static CODEFORCES_RUST_VERSION: Version = semver(1, 42, 0);
static YUKICODER_RUST_VERSION: Version = semver(1, 44, 1);

const fn semver(major: u64, minor: u64, patch: u64) -> Version {
    Version {
        major,
        minor,
        patch,
        pre: vec![],
        build: vec![],
    }
}

#[derive(StructOpt, Debug)]
#[structopt(
    about,
    author,
    bin_name("cargo"),
    global_settings(&[AppSettings::DeriveDisplayOrder, AppSettings::UnifiedHelpMessage])
)]
pub enum Opt {
    #[structopt(about, author)]
    Compete(OptCompete),
}

#[derive(StructOpt, Debug)]
pub enum OptCompete {
    /// Create workspaces in a repository
    #[structopt(author, visible_alias("i"))]
    Init(OptCompeteInit),

    /// Login to a platform
    #[structopt(author, visible_alias("l"))]
    Login(OptCompeteLogin),

    /// Register to a contest
    #[structopt(author, visible_alias("p"))]
    Participate(OptCompeteParticipate),

    /// Retrieve data
    #[structopt(author, visible_alias("r"))]
    Retrieve(OptCompeteRetrieve),

    /// Alias for `retrieve testcases`
    #[structopt(author, visible_alias("d"))]
    Download(OptCompeteRetrieveTestcases),

    /// Watch items
    #[structopt(author, visible_alias("w"))]
    Watch(OptCompeteWatch),

    /// Test your code
    #[structopt(author, visible_alias("t"))]
    Test(OptCompeteTest),

    /// Submit your code
    #[structopt(author, visible_alias("s"))]
    Submit(OptCompeteSubmit),
}

#[derive(StructOpt, Debug)]
pub enum OptCompeteRetrieve {
    /// Retrieve test cases
    #[structopt(author, visible_alias("t"))]
    Testcases(OptCompeteRetrieveTestcases),
}

#[derive(StructOpt, Debug)]
pub enum OptCompeteWatch {
    /// Watch submissions
    #[structopt(author, visible_alias("s"))]
    Submissions(OptCompeteWatchSubmissions),
}

pub struct Context<'s> {
    pub cwd: PathBuf,
    pub shell: &'s mut Shell,
}

pub fn run(opt: OptCompete, ctx: Context<'_>) -> anyhow::Result<()> {
    match opt {
        OptCompete::Init(opt) => commands::init::run(opt, ctx),
        OptCompete::Login(opt) => commands::login::run(opt, ctx),
        OptCompete::Participate(opt) => commands::participate::run(opt, ctx),
        OptCompete::Retrieve(OptCompeteRetrieve::Testcases(opt)) | OptCompete::Download(opt) => {
            commands::retrieve_testcases::run(opt, ctx)
        }
        OptCompete::Watch(OptCompeteWatch::Submissions(opt)) => {
            commands::watch_submissions::run(opt, ctx)
        }
        OptCompete::Test(opt) => commands::test::run(opt, ctx),
        OptCompete::Submit(opt) => commands::submit::run(opt, ctx),
    }
}