add run
command
This commit is contained in:
parent
af46e2a811
commit
a11529717c
27
Cargo.lock
generated
27
Cargo.lock
generated
@ -163,6 +163,8 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"strum",
|
||||
"strum_macros",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
@ -340,6 +342,12 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@ -386,6 +394,25 @@ version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.26.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06"
|
||||
|
||||
[[package]]
|
||||
name = "strum_macros"
|
||||
version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustversion",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.87"
|
||||
|
@ -9,3 +9,5 @@ anyhow = "1.0.93"
|
||||
tokio = { version = "1.10.0", features = ["full"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = "0.3.18"
|
||||
strum = "0.26.3"
|
||||
strum_macros = "0.26.4"
|
||||
|
26
src/cpgen/commands.rs
Normal file
26
src/cpgen/commands.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use crate::lang::Language;
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Clone)]
|
||||
pub enum Command {
|
||||
Init {
|
||||
#[arg(required = true)]
|
||||
contest_urls: Vec<String>,
|
||||
},
|
||||
Gen {
|
||||
#[arg(required = true)]
|
||||
file_dirs: Vec<String>,
|
||||
|
||||
#[arg(short, long)]
|
||||
language: Option<Language>,
|
||||
},
|
||||
Run {
|
||||
file: String,
|
||||
},
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use crate::lang::Language;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use crate::lang::Language;
|
||||
|
||||
pub struct Generator {
|
||||
pub file_dirs: Vec<String>,
|
||||
@ -18,11 +18,11 @@ impl Generator {
|
||||
for file_dir in &self.file_dirs {
|
||||
tracing::info!("Generating files in {}", file_dir);
|
||||
|
||||
let path = PathBuf::try_from(file_dir);
|
||||
match path {
|
||||
#[allow(clippy::unnecessary_fallible_conversions)]
|
||||
match PathBuf::try_from(file_dir) {
|
||||
Ok(file_dir) => {
|
||||
generate(file_dir.to_str().unwrap(), &self.language)?;
|
||||
},
|
||||
}
|
||||
Err(_) => {
|
||||
return Err(anyhow::anyhow!("Invalid path: {}", file_dir));
|
||||
}
|
||||
@ -39,14 +39,21 @@ struct InnerGenerator {
|
||||
impl InnerGenerator {
|
||||
fn new<T: AsRef<str>, S: AsRef<str>>(files: Vec<(T, S)>) -> Self {
|
||||
Self {
|
||||
files: files.into_iter().map(|(t, s)| (t.as_ref().to_string(), s.as_ref().to_string())).collect(),
|
||||
files: files
|
||||
.into_iter()
|
||||
.map(|(t, s)| (t.as_ref().to_string(), s.as_ref().to_string()))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
fn run(self, dir_path: &str) -> anyhow::Result<()> {
|
||||
for (file_name, content) in self.files {
|
||||
let file_path = PathBuf::from(format!("{}/{}", dir_path, file_name));
|
||||
|
||||
std::fs::create_dir_all(file_path.parent().ok_or(anyhow::anyhow!("Invalid parent dir"))?)?;
|
||||
std::fs::create_dir_all(
|
||||
file_path
|
||||
.parent()
|
||||
.ok_or(anyhow::anyhow!("Invalid parent dir"))?,
|
||||
)?;
|
||||
|
||||
let mut file = std::fs::File::create(file_path)?;
|
||||
file.write_all(content.as_bytes())?;
|
||||
@ -56,11 +63,14 @@ impl InnerGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fn generate(dir_path: &str, lang: &Language) -> anyhow::Result<()> {
|
||||
let inner_gen = match lang {
|
||||
Language::Cpp => {
|
||||
let cpp_files = vec![crate::r#static::MAIN_CPP, crate::r#static::BITS, crate::r#static::DBG_H];
|
||||
let cpp_files = vec![
|
||||
crate::r#static::MAIN_CPP,
|
||||
crate::r#static::BITS,
|
||||
crate::r#static::DBG_H,
|
||||
];
|
||||
InnerGenerator::new(cpp_files)
|
||||
}
|
||||
Language::Rust => {
|
@ -1,5 +1,5 @@
|
||||
mod run;
|
||||
mod commands;
|
||||
mod gen;
|
||||
mod run;
|
||||
|
||||
pub use run::*;
|
@ -1,16 +1,24 @@
|
||||
use crate::runner::commands::{Cli, Command};
|
||||
use crate::cpgen::commands::{Cli, Command};
|
||||
use crate::cpgen::gen::Generator;
|
||||
use crate::runner::Runner;
|
||||
use clap::Parser;
|
||||
use crate::runner::gen::Generator;
|
||||
|
||||
pub async fn run() -> anyhow::Result<()> {
|
||||
let cli: Cli = Cli::parse();
|
||||
let command = cli.command;
|
||||
match command {
|
||||
Command::Init { .. } => todo!(),
|
||||
Command::Gen { file_dirs, language } => {
|
||||
Command::Gen {
|
||||
file_dirs,
|
||||
language,
|
||||
} => {
|
||||
let generator = Generator::new(file_dirs, language);
|
||||
generator.generate()?;
|
||||
}
|
||||
Command::Run { file } => {
|
||||
let runner = Runner::new(file);
|
||||
runner.run()?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
@ -1,8 +1,14 @@
|
||||
use clap::ValueEnum;
|
||||
|
||||
#[derive(ValueEnum, Default, Clone)]
|
||||
#[derive(ValueEnum, Default, Clone, strum_macros::EnumIter, strum_macros::Display)]
|
||||
pub enum Language {
|
||||
#[default]
|
||||
Cpp,
|
||||
Rust,
|
||||
}
|
||||
|
||||
impl Language {
|
||||
pub fn extension(&self) -> String {
|
||||
self.to_string().to_lowercase()
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
pub mod runner;
|
||||
pub mod cpgen;
|
||||
pub mod lang;
|
||||
pub mod r#static;
|
||||
|
||||
pub mod runner;
|
||||
|
@ -11,7 +11,7 @@ fn init() -> anyhow::Result<()> {
|
||||
.enable_all()
|
||||
.build()?;
|
||||
|
||||
rt.block_on(cpgen::runner::run())
|
||||
rt.block_on(cpgen::cpgen::run())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
54
src/runner.rs
Normal file
54
src/runner.rs
Normal file
@ -0,0 +1,54 @@
|
||||
use crate::lang::Language;
|
||||
use std::process::Command;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
pub struct Runner {
|
||||
file_path: String,
|
||||
}
|
||||
|
||||
impl Runner {
|
||||
pub fn new(file: String) -> Self {
|
||||
Self { file_path: file }
|
||||
}
|
||||
|
||||
pub fn run(self) -> anyhow::Result<()> {
|
||||
let ext = self
|
||||
.file_path
|
||||
.split(".")
|
||||
.last()
|
||||
.ok_or(anyhow::anyhow!("No file extension"))?
|
||||
.to_string();
|
||||
let lang: Language = Language::iter()
|
||||
.find(|lang| lang.extension() == ext)
|
||||
.ok_or(anyhow::anyhow!("Unsupported file extension"))?;
|
||||
|
||||
let file_name = self
|
||||
.file_path
|
||||
.split("/")
|
||||
.last()
|
||||
.ok_or(anyhow::anyhow!("No file name"))?;
|
||||
|
||||
match lang {
|
||||
Language::Cpp => {
|
||||
Command::new("g++")
|
||||
.arg(file_name)
|
||||
.arg("-o")
|
||||
.arg("main")
|
||||
.arg("-DLOCAL")
|
||||
.arg(&self.file_path)
|
||||
.output()?;
|
||||
}
|
||||
Language::Rust => {
|
||||
Command::new("rustc")
|
||||
.arg(file_name)
|
||||
.arg("--cfg")
|
||||
.arg(r#"'feature="local"'"#)
|
||||
.arg("-o")
|
||||
.arg("main")
|
||||
.output()?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
use clap::{Parser, Subcommand};
|
||||
use crate::lang::Language;
|
||||
|
||||
#[derive(Parser)]
|
||||
pub struct Cli {
|
||||
#[command(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Clone)]
|
||||
pub enum Command {
|
||||
Init {
|
||||
#[arg(required = true)]
|
||||
contest_urls: Vec<String>,
|
||||
},
|
||||
Gen {
|
||||
#[arg(required = true)]
|
||||
file_dirs: Vec<String>,
|
||||
|
||||
#[arg(short, long)]
|
||||
language: Option<Language>,
|
||||
},
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
/// CPP
|
||||
pub const MAIN_CPP: (&'static str, &'static str) = ("main.cpp", include_str!("../cpp/main.cpp"));
|
||||
pub const DBG_H: (&'static str, &'static str) = ("debug.h", include_str!("../cpp/dbg.h"));
|
||||
pub const BITS: (&'static str, &'static str) = ("bits/stdc++.h", include_str!("../cpp/bits/stdc++.h"));
|
||||
pub const CPP_CMD: &'static str = r#"g++ main.cpp -o main -DLOCAL"#;
|
||||
|
||||
pub const MAIN_CPP: (&str, &str) = ("main.cpp", include_str!("../cpp/main.cpp"));
|
||||
pub const DBG_H: (&str, &str) = ("debug.h", include_str!("../cpp/dbg.h"));
|
||||
pub const BITS: (&str, &str) = ("bits/stdc++.h", include_str!("../cpp/bits/stdc++.h"));
|
||||
|
||||
/// Rust
|
||||
pub const MAIN_RS: (&'static str, &'static str) = ("main.rs", include_str!("../rust/main.rs"));
|
||||
pub const RS_CMD: &'static str = r#"rustc main.rs --cfg 'feature="local"'"#;
|
||||
pub const MAIN_RS: (&str, &str) = ("main.rs", include_str!("../rust/main.rs"));
|
||||
|
Loading…
Reference in New Issue
Block a user