1use crate::ConfigureState;2use clap::Parser;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(Parser)]57#[clap(next_help_heading = "EXTERNAL VARIABLES")]58pub struct ExtVarOpts {59 60 61 62 63 64 #[clap(65 long,66 short = 'V',67 name = "name[=var data]",68 number_of_values = 1,69 multiple_occurrences = true70 )]71 ext_str: Vec<ExtStr>,72 73 74 #[clap(75 long,76 name = "name=var path",77 number_of_values = 1,78 multiple_occurrences = true79 )]80 ext_str_file: Vec<ExtFile>,81 82 83 #[clap(84 long,85 name = "name[=var source]",86 number_of_values = 1,87 multiple_occurrences = true88 )]89 ext_code: Vec<ExtStr>,90 91 92 #[clap(93 long,94 name = "name=var code path",95 number_of_values = 1,96 multiple_occurrences = true97 )]98 ext_code_file: Vec<ExtFile>,99}100impl ConfigureState for ExtVarOpts {101 fn configure(&self, state: &EvaluationState) -> Result<()> {102 for ext in self.ext_str.iter() {103 state.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());104 }105 for ext in self.ext_str_file.iter() {106 state.add_ext_str((&ext.name as &str).into(), (&ext.value as &str).into());107 }108 for ext in self.ext_code.iter() {109 state.add_ext_code((&ext.name as &str).into(), (&ext.value as &str).into())?;110 }111 for ext in self.ext_code_file.iter() {112 state.add_ext_code((&ext.name as &str).into(), (&ext.value as &str).into())?;113 }114 Ok(())115 }116}