Basic repl
This commit is contained in:
commit
ecbfce64ed
20 changed files with 565 additions and 0 deletions
2
.cargo/config.toml
Normal file
2
.cargo/config.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[alias]
|
||||||
|
xtask = "run --quiet --package xtask --"
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*.obj filter=lfs diff=lfs merge=lfs -text
|
29
.github/workflows/rust.yml
vendored
Normal file
29
.github/workflows/rust.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
name: Rust
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main", "master" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main", "master" ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cargo build --verbose
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: cargo test --verbose
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: cargo fmt -- --check
|
||||||
|
|
||||||
|
- name: Clippy
|
||||||
|
run: cargo clippy -- -D warnings
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/target
|
||||||
|
.idea
|
||||||
|
Cargo.lock
|
||||||
|
*.log
|
21
LICENSE.md
Normal file
21
LICENSE.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# MIT License
|
||||||
|
|
||||||
|
## Copyright (c) 2024 Caznix
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.**
|
0
README.md
Normal file
0
README.md
Normal file
7
cargo.toml
Normal file
7
cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[workspace]
|
||||||
|
resolver = "2"
|
||||||
|
members = [
|
||||||
|
"engine",
|
||||||
|
"editor",
|
||||||
|
"xtask"
|
||||||
|
]
|
7
editor/Cargo.toml
Normal file
7
editor/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "editor"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
floem = "0.2.0"
|
18
editor/src/main.rs
Normal file
18
editor/src/main.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
use floem::{prelude::*, style::Style};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
floem::launch(counter_view);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn counter_view() -> impl IntoView {
|
||||||
|
let mut counter = RwSignal::new(20);
|
||||||
|
v_stack({
|
||||||
|
label("test")
|
||||||
|
}).style(Style::d);
|
||||||
|
h_stack((
|
||||||
|
button("Increment").action(move || counter += 1),
|
||||||
|
label(move || format!("Value: {counter}")),
|
||||||
|
button("Decrement").action(move || counter -= 1),
|
||||||
|
))
|
||||||
|
.style(|s| s.size_full().items_center().justify_center().gap(10))
|
||||||
|
}
|
1
engine/.gitignore
vendored
Normal file
1
engine/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
16
engine/Cargo.toml
Normal file
16
engine/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "zenyx"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
chrono = "0.4.38"
|
||||||
|
colored = "2.1.0"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
|
#log = "0.4.22"
|
||||||
|
log2 = "0.1.14"
|
||||||
|
parking_lot = "0.12.3"
|
||||||
|
reedline = "0.37.0"
|
||||||
|
regex = "1.11.1"
|
||||||
|
thiserror = "2.0.3"
|
||||||
|
tokio = { version = "1.41.1", features = ["macros", "rt", "rt-multi-thread"] }
|
36
engine/src/core/commands.rs
Normal file
36
engine/src/core/commands.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
use log2::{debug, info};
|
||||||
|
|
||||||
|
use crate::core::repl::COMMAND_LIST;
|
||||||
|
|
||||||
|
pub fn say_hello() {
|
||||||
|
println!("Hello from your new command!");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn echo(args: Vec<String>) {
|
||||||
|
debug!("{}", args.join(" "));
|
||||||
|
println!("{}", args.join(" "))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exit() {
|
||||||
|
debug!("Exiting...");
|
||||||
|
std::process::exit(0)
|
||||||
|
}
|
||||||
|
pub fn clear() {
|
||||||
|
info!("Clearing screen..., running command");
|
||||||
|
let _result = if cfg!(target_os = "windows") {
|
||||||
|
debug!("target_os is windows");
|
||||||
|
Command::new("cmd").args(["/c", "cls"]).spawn()
|
||||||
|
} else {
|
||||||
|
debug!("target_os was unix");
|
||||||
|
// "clear" or "tput reset"
|
||||||
|
Command::new("tput").arg("reset").spawn()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub fn cmds() {
|
||||||
|
println!("Commands:");
|
||||||
|
for cmd in COMMAND_LIST.commands.read().iter() {
|
||||||
|
println!("{:#}", cmd);
|
||||||
|
}
|
||||||
|
}
|
3
engine/src/core/mod.rs
Normal file
3
engine/src/core/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub mod commands;
|
||||||
|
pub mod repl;
|
||||||
|
pub mod splash;
|
248
engine/src/core/repl.rs
Normal file
248
engine/src/core/repl.rs
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
use super::commands;
|
||||||
|
use chrono::Local;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use log2::{debug, error, info};
|
||||||
|
use parking_lot::RwLock;
|
||||||
|
use reedline::{Prompt, Reedline, Signal};
|
||||||
|
use regex::Regex;
|
||||||
|
use std::{borrow::Borrow, collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
|
struct ZPrompt {
|
||||||
|
left_text: String,
|
||||||
|
right_text: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
enum Callable {
|
||||||
|
Simple(fn()),
|
||||||
|
WithArgs(fn(Vec<String>)),
|
||||||
|
}
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Command {
|
||||||
|
pub name: &'static str,
|
||||||
|
pub description: Option<&'static str>,
|
||||||
|
function: Callable,
|
||||||
|
pub arg_count: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command {
|
||||||
|
pub fn execute(&self, args: Option<Vec<String>>) {
|
||||||
|
//debug!("Executing command: {}", self.name);
|
||||||
|
match &self.function {
|
||||||
|
Callable::Simple(f) => {
|
||||||
|
if let Some(args) = args {
|
||||||
|
error!(
|
||||||
|
"Command expected 0 arguments but {} args were given. Ignoring..",
|
||||||
|
args.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
Callable::WithArgs(f) => match args {
|
||||||
|
Some(args) => f(args),
|
||||||
|
None => error!("Command expected arguments but received 0"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Command {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Name: {}\n\t{}",
|
||||||
|
self.name,
|
||||||
|
self.description.unwrap_or("No description")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref COMMAND_LIST: Arc<CommandList> = Arc::new(CommandList::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CommandList {
|
||||||
|
pub commands: RwLock<Vec<Command>>,
|
||||||
|
pub aliases: RwLock<HashMap<String, String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandList {
|
||||||
|
fn new() -> Self {
|
||||||
|
CommandList {
|
||||||
|
commands: RwLock::new(Vec::new()),
|
||||||
|
aliases: RwLock::new(HashMap::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_command(
|
||||||
|
&self,
|
||||||
|
name: &'static str,
|
||||||
|
description: Option<&'static str>,
|
||||||
|
func: Callable,
|
||||||
|
arg_count: Option<u8>,
|
||||||
|
) {
|
||||||
|
debug!("Adding command: {}", name);
|
||||||
|
let mut commands = self.commands.write();
|
||||||
|
|
||||||
|
commands.push(Command {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
function: func,
|
||||||
|
arg_count: arg_count.unwrap_or(0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fn add_alias(&self, name: String, alias: String) {
|
||||||
|
//println!("Input alias: {}", alias);
|
||||||
|
if self.aliases.read().contains_key(&alias) {
|
||||||
|
error!("Alias: '{}' already exists", alias);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut commands = self.commands.write();
|
||||||
|
if let Some(command) = commands.iter_mut().find(|cmd| cmd.name == name) {
|
||||||
|
info!("Adding alias: {} for cmd: {}", alias, command.name);
|
||||||
|
self.aliases
|
||||||
|
.write()
|
||||||
|
.insert(alias.to_string(), name.to_string());
|
||||||
|
} else {
|
||||||
|
error!("Command: '{}' was not found", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_command(&self, mut name: String, args: Option<Vec<String>>) {
|
||||||
|
//info!("received input command: {}", name);
|
||||||
|
let commands = self.commands.borrow();
|
||||||
|
if self.aliases.read().contains_key(&name) {
|
||||||
|
name = self
|
||||||
|
.aliases
|
||||||
|
.read()
|
||||||
|
.get_key_value(&name)
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.to_string();
|
||||||
|
debug!("changed to {}", name);
|
||||||
|
}
|
||||||
|
if let Some(command) = commands.read().iter().find(|cmd| cmd.name == name) { match (command.arg_count, args.as_ref()) {
|
||||||
|
(expected, Some(args_vec)) if args_vec.len() != expected as usize => {
|
||||||
|
eprintln!(
|
||||||
|
"Command: '{}' expected {} arguments but received {}",
|
||||||
|
name,
|
||||||
|
expected,
|
||||||
|
args_vec.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
(_, _) => command.execute(args),
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Prompt for ZPrompt {
|
||||||
|
fn render_prompt_left(&self) -> std::borrow::Cow<str> {
|
||||||
|
std::borrow::Cow::Borrowed(&self.left_text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_prompt_right(&self) -> std::borrow::Cow<str> {
|
||||||
|
std::borrow::Cow::Borrowed(&self.right_text)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_prompt_history_search_indicator(
|
||||||
|
&self,
|
||||||
|
_history_search: reedline::PromptHistorySearch,
|
||||||
|
) -> std::borrow::Cow<str> {
|
||||||
|
std::borrow::Cow::Borrowed("")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_prompt_indicator(
|
||||||
|
&self,
|
||||||
|
prompt_mode: reedline::PromptEditMode,
|
||||||
|
) -> std::borrow::Cow<str> {
|
||||||
|
match prompt_mode {
|
||||||
|
reedline::PromptEditMode::Default => std::borrow::Cow::Borrowed(">>"),
|
||||||
|
reedline::PromptEditMode::Emacs => {
|
||||||
|
let timestamp = Local::now().format("[%H:%M:%S.%3f/SHELL] >>\t").to_string();
|
||||||
|
std::borrow::Cow::Owned(timestamp)
|
||||||
|
}
|
||||||
|
reedline::PromptEditMode::Vi(_) => std::borrow::Cow::Borrowed("vi>>"),
|
||||||
|
reedline::PromptEditMode::Custom(_) => std::borrow::Cow::Borrowed("custom>>"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_prompt_multiline_indicator(&self) -> std::borrow::Cow<str> {
|
||||||
|
std::borrow::Cow::Borrowed("><")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup() {
|
||||||
|
COMMAND_LIST.add_command(
|
||||||
|
"hello",
|
||||||
|
Some("test"),
|
||||||
|
Callable::Simple(commands::say_hello),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
COMMAND_LIST.add_command("exit", None, Callable::Simple(commands::exit), None);
|
||||||
|
COMMAND_LIST.add_command("clear", None, Callable::Simple(commands::clear), None);
|
||||||
|
COMMAND_LIST.add_command("echo", None, Callable::WithArgs(commands::echo), Some(1));
|
||||||
|
COMMAND_LIST.add_command("cmds", None, Callable::Simple(commands::cmds), None);
|
||||||
|
COMMAND_LIST.add_alias("cmds".to_string(), "help".to_string());
|
||||||
|
COMMAND_LIST.add_alias("cmds".to_string(), "cmd_list".to_string());
|
||||||
|
COMMAND_LIST.add_alias("hello".to_string(), "exit".to_string());
|
||||||
|
COMMAND_LIST.add_alias("clear".to_string(), "exit".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn handle_repl() {
|
||||||
|
let mut line_editor = Reedline::create();
|
||||||
|
setup();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let sig = line_editor.read_line(&ZPrompt {
|
||||||
|
left_text: String::new(),
|
||||||
|
right_text: "<<".to_string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
match sig {
|
||||||
|
Ok(Signal::Success(buffer)) => {
|
||||||
|
if buffer == "exit" {
|
||||||
|
std::process::exit(0);
|
||||||
|
} else {
|
||||||
|
evaluate_command(&buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Signal::CtrlC) => {
|
||||||
|
println!("\nCONTROL+C RECEIVED, TERMINATING");
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
err => {
|
||||||
|
eprintln!("Error: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evaluate_command(input: &str) {
|
||||||
|
if input.trim().is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pattern = Regex::new(r"[;|\n]").unwrap();
|
||||||
|
let commands: Vec<&str> = pattern.split(input).collect();
|
||||||
|
|
||||||
|
for command in commands {
|
||||||
|
let command = command.trim();
|
||||||
|
if command.is_empty() {
|
||||||
|
println!("Empty command, skipping.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tokens: Vec<&str> = command.split_whitespace().collect();
|
||||||
|
if tokens.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cmd_name = tokens[0];
|
||||||
|
let args: Vec<String> = tokens[1..].iter().map(|&s| s.to_string()).collect();
|
||||||
|
|
||||||
|
COMMAND_LIST.execute_command(
|
||||||
|
cmd_name.to_string(),
|
||||||
|
if args.is_empty() { None } else { Some(args) },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
26
engine/src/core/splash.rs
Normal file
26
engine/src/core/splash.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
use colored::Colorize;
|
||||||
|
|
||||||
|
pub fn print_splash() {
|
||||||
|
println!(
|
||||||
|
r#"
|
||||||
|
&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&&&&&&&&&&&
|
||||||
|
&& &&&&&&&&&
|
||||||
|
&& &&&&&&&&&
|
||||||
|
&&&&&&&&&&&& &&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&&& &&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&&& &&&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&& &&&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&& &&&&&&&&&&&&
|
||||||
|
&&&&&&&&& &&
|
||||||
|
&&&&&&&&& &&
|
||||||
|
&&&&&&&&&&&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&&&&&&&
|
||||||
|
&&&&&&&&&&&
|
||||||
|
|
||||||
|
Version: {}
|
||||||
|
"#,
|
||||||
|
env!("CARGO_PKG_VERSION").yellow().italic().underline()
|
||||||
|
);
|
||||||
|
}
|
21
engine/src/main.rs
Normal file
21
engine/src/main.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
use log2::info;
|
||||||
|
|
||||||
|
pub mod core;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), io::Error> {
|
||||||
|
let _log2 = log2::open("z.log").tee(true).level("trace").start();
|
||||||
|
info!("Initalizing Engine");
|
||||||
|
let shell_thread = tokio::task::spawn(async {
|
||||||
|
info!("Shell thread started");
|
||||||
|
core::repl::handle_repl().await;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
core::splash::print_splash();
|
||||||
|
info!("Engine Initalized");
|
||||||
|
shell_thread.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
32
xtask/Cargo.toml
Normal file
32
xtask/Cargo.toml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
[package]
|
||||||
|
name = "xtask"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.5.20", features = ["derive"] }
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
rpath = false
|
||||||
|
panic = "abort"
|
||||||
|
lto = "off"
|
||||||
|
opt-level = 0
|
||||||
|
debug = false
|
||||||
|
overflow-checks = false
|
||||||
|
incremental = true
|
||||||
|
codegen-units = 256
|
||||||
|
|
||||||
|
strip = "symbols"
|
||||||
|
debug-assertions = false
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
opt-level = 0
|
||||||
|
debug = false
|
||||||
|
overflow-checks = false
|
||||||
|
incremental = true
|
||||||
|
codegen-units = 256
|
||||||
|
|
||||||
|
strip = "symbols"
|
||||||
|
debug-assertions = false
|
||||||
|
|
1
xtask/src/editor.rs
Normal file
1
xtask/src/editor.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub fn build_editor() {}
|
22
xtask/src/engine.rs
Normal file
22
xtask/src/engine.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
use std::process::Stdio;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn build_engine() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_core() {
|
||||||
|
let threads = format!("-j{}",std::thread::available_parallelism().unwrap().get());
|
||||||
|
let mut run = std::process::Command::new("cargo")
|
||||||
|
.arg("run")
|
||||||
|
|
||||||
|
.arg(threads)
|
||||||
|
.arg("--bin")
|
||||||
|
.arg("zenyx")
|
||||||
|
.stdin(Stdio::inherit())
|
||||||
|
.stdout(Stdio::inherit())
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
run.wait().unwrap();
|
||||||
|
}
|
70
xtask/src/main.rs
Normal file
70
xtask/src/main.rs
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
use clap::{CommandFactory, Parser, Subcommand, ValueEnum};
|
||||||
|
pub mod engine;
|
||||||
|
pub mod editor;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(version, about, long_about = None,disable_version_flag = true,disable_help_flag = true)]
|
||||||
|
struct Cli {
|
||||||
|
#[arg(short,long)]
|
||||||
|
release: bool,
|
||||||
|
#[command(subcommand)]
|
||||||
|
command: Option<Commands>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subcommand)]
|
||||||
|
enum Commands {
|
||||||
|
Run {
|
||||||
|
#[arg()]
|
||||||
|
task: Task
|
||||||
|
},
|
||||||
|
Config,
|
||||||
|
|
||||||
|
}
|
||||||
|
#[derive(Clone,ValueEnum)]
|
||||||
|
enum Task {
|
||||||
|
Engine, // Builds both editor and core
|
||||||
|
Editor, // Builds editor only
|
||||||
|
Core, // Builds engine core only
|
||||||
|
Help,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let cli = Cli::parse();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if cli.release {
|
||||||
|
println!("Running in release mode")
|
||||||
|
}
|
||||||
|
|
||||||
|
match &cli.command {
|
||||||
|
|
||||||
|
None => {
|
||||||
|
Cli::command().print_help().map_err(|e| {
|
||||||
|
println!("Could not run Xtask: {e}");
|
||||||
|
|
||||||
|
}).unwrap();
|
||||||
|
}
|
||||||
|
Some(Commands::Run { task }) => {
|
||||||
|
match task {
|
||||||
|
Task::Engine => engine::build_engine(),
|
||||||
|
Task::Editor => todo!("Editor is not being actively worked on"),
|
||||||
|
Task::Core => {
|
||||||
|
engine::build_core();
|
||||||
|
},
|
||||||
|
Task::Help => {
|
||||||
|
println!("The following options are avalible to run");
|
||||||
|
todo!()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Commands::Config) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue