|
| 1 | +use anyhow::{Context, Result}; |
| 2 | +use cairo_lang_runner::Arg; |
| 3 | +use cairo_lang_utils::bigint::BigUintAsHex; |
| 4 | +use camino::Utf8PathBuf; |
| 5 | +use clap::{arg, Parser, ValueEnum}; |
| 6 | +use num_bigint::BigInt; |
| 7 | +use scarb_ui::args::{PackagesFilter, VerbositySpec}; |
| 8 | +use std::fs; |
| 9 | + |
| 10 | +/// Compiles a Cairo project and runs a function marked `#[executable]`. |
| 11 | +/// Exits with 1 if the compilation or run fails, otherwise 0. |
| 12 | +#[derive(Parser, Clone, Debug)] |
| 13 | +#[clap(version, verbatim_doc_comment)] |
| 14 | +pub struct Args { |
| 15 | + /// Name of the package. |
| 16 | + #[command(flatten)] |
| 17 | + pub packages_filter: PackagesFilter, |
| 18 | + |
| 19 | + /// Do not rebuild the package. |
| 20 | + #[arg(long, default_value_t = false)] |
| 21 | + pub no_build: bool, |
| 22 | + |
| 23 | + #[clap(flatten)] |
| 24 | + pub run: ExecutionArgs, |
| 25 | + |
| 26 | + /// Logging verbosity. |
| 27 | + #[command(flatten)] |
| 28 | + pub verbose: VerbositySpec, |
| 29 | +} |
| 30 | + |
| 31 | +#[derive(Parser, Clone, Debug)] |
| 32 | +pub struct ExecutionArgs { |
| 33 | + #[command(flatten)] |
| 34 | + pub arguments: ProgramArguments, |
| 35 | + |
| 36 | + /// Desired execution output, either default Standard or CairoPie |
| 37 | + #[arg(long, default_value = "standard")] |
| 38 | + pub output: OutputFormat, |
| 39 | + |
| 40 | + /// Execution target. |
| 41 | + #[arg(long, default_value = "standalone")] |
| 42 | + pub target: ExecutionTarget, |
| 43 | + |
| 44 | + /// Whether to print the program outputs. |
| 45 | + #[arg(long, default_value_t = false)] |
| 46 | + pub print_program_output: bool, |
| 47 | +} |
| 48 | + |
| 49 | +#[derive(Parser, Debug, Clone)] |
| 50 | +pub struct ProgramArguments { |
| 51 | + /// Serialized arguments to the executable function. |
| 52 | + #[arg(long, value_delimiter = ',')] |
| 53 | + pub arguments: Vec<BigInt>, |
| 54 | + |
| 55 | + /// Serialized arguments to the executable function from a file. |
| 56 | + #[arg(long, conflicts_with = "arguments")] |
| 57 | + pub arguments_file: Option<Utf8PathBuf>, |
| 58 | +} |
| 59 | + |
| 60 | +impl ProgramArguments { |
| 61 | + pub fn read_arguments(self) -> Result<Vec<Arg>> { |
| 62 | + if let Some(path) = self.arguments_file { |
| 63 | + let file = fs::File::open(&path).with_context(|| "reading arguments file failed")?; |
| 64 | + let as_vec: Vec<BigUintAsHex> = serde_json::from_reader(file) |
| 65 | + .with_context(|| "deserializing arguments file failed")?; |
| 66 | + Ok(as_vec |
| 67 | + .into_iter() |
| 68 | + .map(|v| Arg::Value(v.value.into())) |
| 69 | + .collect()) |
| 70 | + } else { |
| 71 | + Ok(self |
| 72 | + .arguments |
| 73 | + .iter() |
| 74 | + .map(|v| Arg::Value(v.into())) |
| 75 | + .collect()) |
| 76 | + } |
| 77 | + } |
| 78 | +} |
| 79 | + |
| 80 | +#[derive(ValueEnum, Clone, Debug)] |
| 81 | +pub enum OutputFormat { |
| 82 | + CairoPie, |
| 83 | + Standard, |
| 84 | +} |
| 85 | +impl OutputFormat { |
| 86 | + pub fn is_standard(&self) -> bool { |
| 87 | + matches!(self, OutputFormat::Standard) |
| 88 | + } |
| 89 | + pub fn is_cairo_pie(&self) -> bool { |
| 90 | + matches!(self, OutputFormat::CairoPie) |
| 91 | + } |
| 92 | +} |
| 93 | + |
| 94 | +#[derive(ValueEnum, Clone, Debug)] |
| 95 | +pub enum ExecutionTarget { |
| 96 | + Bootloader, |
| 97 | + Standalone, |
| 98 | +} |
| 99 | + |
| 100 | +impl ExecutionTarget { |
| 101 | + pub fn is_standalone(&self) -> bool { |
| 102 | + matches!(self, ExecutionTarget::Standalone) |
| 103 | + } |
| 104 | +} |
0 commit comments