git.delta.rocks / jrsonnet / refs/commits / 30ce98effbb6

difftreelog

source

cmds/jsonnet/src/main.rs2.8 KiBsourcehistory
1use clap::Clap;2use jsonnet_evaluator::Val;3use std::str::FromStr;45enum Format {6	None,7	Json,8}910impl FromStr for Format {11	type Err = &'static str;12	fn from_str(s: &str) -> Result<Self, Self::Err> {13		Ok(match s {14			"none" => Format::None,15			"json" => Format::Json,16			_ => return Err("no such format"),17		})18	}19}2021#[derive(Clap)]22#[clap(version = "0.1.0", author = "Lach <iam@lach.pw>")]23struct Opts {24	#[clap(long, about = "Disable global std variable")]25	no_stdlib: bool,26	#[clap(long, about = "Add external string")]27	ext_str: Option<Vec<String>>,28	#[clap(long, about = "Add external string from code")]29	ext_code: Option<Vec<String>>,30	#[clap(long, about = "Add TLA")]31	tla_str: Option<Vec<String>>,32	#[clap(long, about = "Add TLA from code")]33	tla_code: Option<Vec<String>>,34	#[clap(long, short = "f", default_value = "json", possible_values = &["none", "json"])]35	format: Format,36	#[clap(about = "File to compile")]37	input: String,38}3940fn main() {41	let opts: Opts = Opts::parse();42	let evaluator = jsonnet_evaluator::EvaluationState::default();43	if !opts.no_stdlib {44		evaluator.add_stdlib();45	}46	evaluator47		.add_file(48			opts.input.clone(),49			String::from_utf8(std::fs::read(opts.input.clone()).unwrap()).unwrap(),50		)51		.unwrap();52	let result = evaluator.evaluate_file(&opts.input);53	match result {54		Ok(mut v) => {55			if let Format::Json = opts.format {56				if opts.no_stdlib {57					evaluator.add_stdlib();58				}59				evaluator.add_global("__tmp__to_json__".to_owned(), v);60				v = evaluator61					.parse_evaluate_raw("std.manifestJsonEx(__tmp__to_json__, \"  \")")62					.expect("json serialization");63			}64			match v {65			Val::Str(s) => println!("{}", s),66			Val::Num(n) => println!("{}", n),67			_v => eprintln!(68				"jsonnet output is not a string.\nDid you forgot to set --format, or wrap your data with std.manifestJson?"69			),70		}71		}72		Err(err) => {73			println!("Error: {:?}", err.0);74			use annotate_snippets::{75				display_list::{DisplayList, FormatOptions},76				snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation},77			};78			for item in (err.1).0.iter() {79				let desc = &item.1;80				if (item.0).1.is_none() {81					continue;82				}83				let source = (item.0).1.clone().unwrap();84				let code = evaluator.get_source(&source.0);85				let snippet = Snippet {86					opt: FormatOptions {87						color: true,88						..Default::default()89					},90					title: Some(Annotation {91						label: Some(&item.1),92						id: None,93						annotation_type: AnnotationType::Error,94					}),95					footer: vec![],96					slices: vec![Slice {97						source: &code,98						line_start: 1,99						origin: Some(&source.0),100						fold: true,101						annotations: vec![SourceAnnotation {102							label: desc,103							annotation_type: AnnotationType::Error,104							range: (source.1, source.2),105						}],106					}],107				};108109				let dl = DisplayList::from(snippet);110				println!("{}", dl);111			}112		}113	}114}