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}1213141516171819202122232425262728293031impl FromStr for ExtStr {32 type Err = &'static str;3334 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {35 match s.find('=') {36 Some(idx) => Ok(Self {37 name: s[..idx].to_owned(),38 value: s[idx + 1..].to_owned(),39 }),40 None => Ok(Self {41 name: s.to_owned(),42 value: std::env::var(s).or(Err("missing env var"))?,43 }),44 }45 }46}4748#[derive(Clone)]49pub struct ExtFile {50 pub name: String,51 pub path: String,52}5354impl FromStr for ExtFile {55 type Err = String;5657 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {58 let Some((name, path)) = s.split_once('=') else {59 return Err("bad ext-file syntax".to_owned());60 };61 Ok(Self {62 name: name.into(),63 path: path.into(),64 })65 }66}6768#[derive(Parser)]69#[clap(next_help_heading = "STANDARD LIBRARY")]70pub struct StdOpts {71 72 73 #[clap(long)]74 no_stdlib: bool,75 76 77 78 79 80 #[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]81 ext_str: Vec<ExtStr>,82 83 84 #[clap(long, name = "name=var path", number_of_values = 1)]85 ext_str_file: Vec<ExtFile>,86 87 88 #[clap(long, name = "name[=var source]", number_of_values = 1)]89 ext_code: Vec<ExtStr>,90 91 92 #[clap(long, name = "name=var code path", number_of_values = 1)]93 ext_code_file: Vec<ExtFile>,94}95impl StdOpts {96 pub fn context_initializer(&self) -> Result<Option<ContextInitializer>> {97 if self.no_stdlib {98 return Ok(None);99 }100 let ctx = ContextInitializer::new(PathResolver::new_cwd_fallback());101 for ext in &self.ext_str {102 ctx.settings_mut().ext_vars.insert(103 ext.name.as_str().into(),104 TlaArg::String(ext.value.as_str().into()),105 );106 }107 for ext in &self.ext_str_file {108 ctx.settings_mut().ext_vars.insert(109 ext.name.as_str().into(),110 TlaArg::ImportStr(ext.path.clone()),111 );112 }113 for ext in &self.ext_code {114 ctx.settings_mut().ext_vars.insert(115 ext.name.as_str().into(),116 TlaArg::InlineCode(ext.value.clone()),117 );118 }119 for ext in &self.ext_code_file {120 ctx.settings_mut()121 .ext_vars122 .insert(ext.name.as_str().into(), TlaArg::Import(ext.path.clone()));123 }124 Ok(Some(ctx))125 }126}