1use std::str::FromStr;23use clap::Parser;4use jrsonnet_evaluator::{Result, tla::TlaArg, trace::PathResolver};5use jrsonnet_stdlib::ContextInitializer;67#[derive(Clone)]8pub struct ExtStr {9 pub name: String,10 pub value: String,11}1213141516171819202122232425262728293031323334353637impl FromStr for ExtStr {38 type Err = &'static str;3940 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {41 match s.find('=') {42 Some(idx) => Ok(Self {43 name: s[..idx].to_owned(),44 value: s[idx + 1..].to_owned(),45 }),46 None => Ok(Self {47 name: s.to_owned(),48 value: std::env::var(s).or(Err("missing env var"))?,49 }),50 }51 }52}5354#[derive(Clone)]55pub struct ExtFile {56 pub name: String,57 pub path: String,58}5960impl FromStr for ExtFile {61 type Err = String;6263 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {64 let Some((name, path)) = s.split_once('=') else {65 return Err("bad ext-file syntax".to_owned());66 };67 Ok(Self {68 name: name.into(),69 path: path.into(),70 })71 }72}7374#[derive(Parser)]75#[clap(next_help_heading = "STANDARD LIBRARY")]76pub struct StdOpts {77 78 79 #[clap(long)]80 no_stdlib: bool,81 82 83 84 85 86 #[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]87 ext_str: Vec<ExtStr>,88 89 90 #[clap(long, name = "name=var path", number_of_values = 1)]91 ext_str_file: Vec<ExtFile>,92 93 94 #[clap(long, name = "name[=var source]", number_of_values = 1)]95 ext_code: Vec<ExtStr>,96 97 98 #[clap(long, name = "name=var code path", number_of_values = 1)]99 ext_code_file: Vec<ExtFile>,100}101impl StdOpts {102 pub fn context_initializer(&self) -> Result<Option<ContextInitializer>> {103 if self.no_stdlib {104 return Ok(None);105 }106 let ctx = ContextInitializer::new(PathResolver::new_cwd_fallback());107 for ext in &self.ext_str {108 ctx.settings_mut().ext_vars.insert(109 ext.name.as_str().into(),110 TlaArg::String(ext.value.as_str().into()),111 );112 }113 for ext in &self.ext_str_file {114 ctx.settings_mut().ext_vars.insert(115 ext.name.as_str().into(),116 TlaArg::ImportStr(ext.path.clone()),117 );118 }119 for ext in &self.ext_code {120 ctx.settings_mut().ext_vars.insert(121 ext.name.as_str().into(),122 TlaArg::InlineCode(ext.value.clone()),123 );124 }125 for ext in &self.ext_code_file {126 ctx.settings_mut()127 .ext_vars128 .insert(ext.name.as_str().into(), TlaArg::Import(ext.path.clone()));129 }130 Ok(Some(ctx))131 }132}