1use crate::ConfigureState;2use clap::Clap;3use jrsonnet_evaluator::{error::Result, EvaluationState};4use std::{fs::read_to_string, str::FromStr};56#[derive(Clone)]7pub struct ExtStr {8 pub name: String,9 pub value: String,10}1112impl FromStr for ExtStr {13 type Err = &'static str;14 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {15 let out: Vec<_> = s.split('=').collect();16 match out.len() {17 1 => Ok(ExtStr {18 name: out[0].to_owned(),19 value: std::env::var(out[0]).or(Err("missing env var"))?,20 }),21 2 => Ok(ExtStr {22 name: out[0].to_owned(),23 value: out[1].to_owned(),24 }),2526 _ => Err("bad ext-str syntax"),27 }28 }29}3031#[derive(Clone)]32pub struct ExtFile {33 pub name: String,34 pub value: String,35}3637impl FromStr for ExtFile {38 type Err = String;3940 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {41 let out: Vec<&str> = s.split('=').collect();42 if out.len() != 2 {43 return Err("bad ext-file syntax".to_owned());44 }45 let file = read_to_string(&out[1]);46 match file {47 Ok(content) => Ok(Self {48 name: out[0].into(),49 value: content,50 }),51 Err(e) => Err(format!("{}", e)),52 }53 }54}5556#[derive(Clap)]57#[clap(help_heading = "EXTERNAL VARIABLES")]58pub struct ExtVarOpts {59 60 61 62 63 64 #[clap(long, short = 'V', name = "name[=var data]", number_of_values = 1)]65 ext_str: Vec<ExtStr>,66 67 68 #[clap(long, name = "name=var path", number_of_values = 1)]69 ext_str_file: Vec<ExtFile>,70 71 72 #[clap(long, name = "name[=var source]", number_of_values = 1)]73 ext_code: Vec<ExtStr>,74 75 76 #[clap(long, name = "name=var code path", number_of_values = 1)]77 ext_code_file: Vec<ExtFile>,78}79impl ConfigureState for ExtVarOpts {80 fn configure(&self, state: &EvaluationState) -> Result<()> {81 for ext in self.ext_str.iter() {82 state.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());83 }84 for ext in self.ext_str_file.iter() {85 state.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());86 }87 for ext in self.ext_code.iter() {88 state.add_ext_code((&ext.name as &str).into(), (&ext.value as &str).into())?;89 }90 for ext in self.ext_code_file.iter() {91 state.add_ext_code((&ext.name as &str).into(), (&ext.value as &str).into())?;92 }93 Ok(())94 }95}