1use std::{fs::read_to_string, str::FromStr};23use clap::Parser;4use jrsonnet_evaluator::{error::Result, tb, trace::PathResolver, State};5use jrsonnet_stdlib::ContextInitializer;67#[derive(Clone)]8pub struct ExtStr {9 pub name: String,10 pub value: String,11}1213impl FromStr for ExtStr {14 type Err = &'static str;15 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {16 let out: Vec<_> = s.split('=').collect();17 match out.len() {18 1 => Ok(ExtStr {19 name: out[0].to_owned(),20 value: std::env::var(out[0]).or(Err("missing env var"))?,21 }),22 2 => Ok(ExtStr {23 name: out[0].to_owned(),24 value: out[1].to_owned(),25 }),2627 _ => Err("bad ext-str syntax"),28 }29 }30}3132#[derive(Clone)]33pub struct ExtFile {34 pub name: String,35 pub value: String,36}3738impl FromStr for ExtFile {39 type Err = String;4041 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {42 let out: Vec<&str> = s.split('=').collect();43 if out.len() != 2 {44 return Err("bad ext-file syntax".to_owned());45 }46 let file = read_to_string(out[1]);47 match file {48 Ok(content) => Ok(Self {49 name: out[0].into(),50 value: content,51 }),52 Err(e) => Err(format!("{}", e)),53 }54 }55}5657#[derive(Parser)]58#[clap(next_help_heading = "STANDARD LIBRARY")]59pub struct StdOpts {60 61 62 #[clap(long)]63 no_stdlib: bool,64 65 66 67 68 69 #[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]70 ext_str: Vec<ExtStr>,71 72 73 #[clap(long, name = "name=var path", number_of_values = 1)]74 ext_str_file: Vec<ExtFile>,75 76 77 #[clap(long, name = "name[=var source]", number_of_values = 1)]78 ext_code: Vec<ExtStr>,79 80 81 #[clap(long, name = "name=var code path", number_of_values = 1)]82 ext_code_file: Vec<ExtFile>,83}84impl StdOpts {85 pub fn context_initializer(&self, s: &State) -> Result<Option<ContextInitializer>> {86 if self.no_stdlib {87 return Ok(None);88 }89 let ctx =90 ContextInitializer::new(s.clone(), PathResolver::new_cwd_fallback());91 for ext in self.ext_str.iter() {92 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());93 }94 for ext in self.ext_str_file.iter() {95 ctx.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());96 }97 for ext in self.ext_code.iter() {98 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;99 }100 for ext in self.ext_code_file.iter() {101 ctx.add_ext_code(&ext.name as &str, &ext.value as &str)?;102 }103 Ok(Some(ctx))104 }105}