add beginnings of simple CLI

This commit is contained in:
Jacob Lifshay 2024-07-21 20:47:52 -07:00
parent 8080cc7b5c
commit 23a77368b3
Signed by: programmerjake
SSH key fingerprint: SHA256:B1iRVvUJkvd7upMIiMqn6OyxvD2SgJkAH3ZnUOj6z+c
4 changed files with 257 additions and 1 deletions

137
Cargo.lock generated
View file

@ -20,6 +20,55 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "anstream"
version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -75,6 +124,52 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]]
name = "colorchoice"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "cpufeatures"
version = "0.2.12"
@ -120,6 +215,16 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "eyre"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "fastrand"
version = "2.0.1"
@ -131,6 +236,8 @@ name = "fayalite"
version = "0.1.0"
dependencies = [
"bitvec",
"clap",
"eyre",
"fayalite-proc-macros",
"fayalite-visit-gen",
"hashbrown",
@ -208,6 +315,18 @@ dependencies = [
"allocator-api2",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "2.2.6"
@ -219,6 +338,12 @@ dependencies = [
"serde",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
[[package]]
name = "itoa"
version = "1.0.10"
@ -368,6 +493,12 @@ dependencies = [
"digest",
]
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.66"
@ -453,6 +584,12 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version_check"
version = "0.9.4"

View file

@ -21,6 +21,8 @@ num-traits = { workspace = true }
fayalite-proc-macros = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
clap = { version = "4.5.9", features = ["derive"] }
eyre = "0.6.12"
[dev-dependencies]
trybuild = { workspace = true }
@ -32,4 +34,4 @@ fayalite-visit-gen = { workspace = true }
unstable-doc = []
[package.metadata.docs.rs]
features = ["unstable-doc"]
features = ["unstable-doc"]

116
crates/fayalite/src/cli.rs Normal file
View file

@ -0,0 +1,116 @@
use crate::{
bundle::{BundleType, BundleValue, DynBundle},
firrtl,
intern::Interned,
module::Module,
};
use clap::{Parser, Subcommand, ValueHint};
use std::{path::PathBuf, process::exit};
#[derive(Subcommand)]
enum CliCommand {
/// Generate FIRRTL
Firrtl {
/// the directory to put the generated FIRRTL and associated files in
#[arg(short, long, value_hint = ValueHint::DirPath)]
output: PathBuf,
/// the stem of the generated .fir file, e.g. to get foo.fir, pass --file-stem=foo
#[arg(long)]
file_stem: Option<String>,
},
}
/// a simple CLI
///
/// Use like:
///
/// ```no_run
/// # use fayalite::{hdl_module, cli::Cli};
/// # #[hdl_module]
/// # fn my_module() {}
/// fn main() {
/// Cli::parse().run(my_module());
/// }
/// ```
///
/// You can also use it with a larger [`clap`]-based CLI like so:
///
/// ```no_run
/// # use fayalite::{hdl_module};
/// # #[hdl_module]
/// # fn my_module() {}
///
/// #[derive(clap::Subcommand)]
/// pub enum Subcommand {
/// #[command(flatten)]
/// Fayalite(fayalite::cli::Cli),
/// MySpecialCommand {
/// #[arg]
/// foo: bool,
/// },
/// }
///
/// #[derive(clap::Parser)]
/// pub struct Cli {
/// #[command(subcommand)]
/// subcommand: Subcommand, // or just use fayalite::cli::Cli directly
/// }
/// fn main() {
/// match Cli::parse().subcommand {
/// Subcommand::Fayalite(v) => v.run(my_module()),
/// Subcommand::MySpecialCommand { foo } => println!("special: foo={foo}"),
/// }
/// }
/// ```
#[derive(Parser)]
// clear things that would be crate-specific
#[command(name = "Fayalite Simple CLI", about = None, long_about = None)]
pub struct Cli {
#[command(subcommand)]
subcommand: CliCommand,
}
impl clap::Subcommand for Cli {
fn augment_subcommands(cmd: clap::Command) -> clap::Command {
CliCommand::augment_subcommands(cmd)
}
fn augment_subcommands_for_update(cmd: clap::Command) -> clap::Command {
CliCommand::augment_subcommands_for_update(cmd)
}
fn has_subcommand(name: &str) -> bool {
CliCommand::has_subcommand(name)
}
}
impl Cli {
/// forwards to [`clap::Parser::parse()`] so you don't have to import [`clap::Parser`]
pub fn parse() -> Self {
clap::Parser::parse()
}
fn run_impl(self, top_module: Module<DynBundle>) -> ! {
match self.subcommand {
CliCommand::Firrtl { output, file_stem } => {
let result = firrtl::export(
firrtl::FileBackend {
dir_path: output,
top_fir_file_stem: file_stem,
},
&top_module,
);
if let Err(e) = result {
eprintln!("Error: {:?}", eyre::Report::new(e));
exit(1);
}
}
}
exit(0)
}
pub fn run<T: BundleValue>(self, top_module: Interned<Module<T>>) -> !
where
T::Type: BundleType<Value = T>,
{
self.run_impl(top_module.canonical())
}
}

View file

@ -27,6 +27,7 @@ pub mod _docs;
pub mod annotations;
pub mod array;
pub mod bundle;
pub mod cli;
pub mod clock;
pub mod enum_;
pub mod expr;