git.delta.rocks / jrsonnet / refs/commits / e53349155ac3

difftreelog

source

cmds/jrsonnet-fmt/src/main.rs7.1 KiBsourcehistory
1use std::path::PathBuf;23use dprint_core::formatting::{PrintItems, PrintOptions, Signal};4use jrsonnet_parser::{5	ArgsDesc, BinaryOpType, BindSpec, Expr, FieldName, LocExpr, Member, ObjBody, Param, ParamsDesc,6	ParserSettings, Visibility,7};89pub trait Printable {10	fn print(&self) -> PrintItems;11}1213macro_rules! pi {14	(@i; $($t:tt)*) => {{15		let mut o = PrintItems::new();16		pi!(@s; o: $($t)*);17		o18	}};19	(@s; $o:ident: str($e:expr) $($t:tt)*) => {{20		$o.push_str($e);21		pi!(@s; $o: $($t)*);22	}};23	(@s; $o:ident: nl $($t:tt)*) => {{24		$o.push_signal(Signal::NewLine);25		pi!(@s; $o: $($t)*);26	}};27	(@s; $o:ident: >i $($t:tt)*) => {{28		$o.push_signal(Signal::StartIndent);29		pi!(@s; $o: $($t)*);30	}};31	(@s; $o:ident: <i $($t:tt)*) => {{32		$o.push_signal(Signal::FinishIndent);33		pi!(@s; $o: $($t)*);34	}};35	(@s; $o:ident: {$expr:expr} $($t:tt)*) => {{36		$o.extend($expr.print());37		pi!(@s; $o: $($t)*);38	}};39	(@s; $o:ident: if ($e:expr)($($then:tt)*) $($t:tt)*) => {{40		if $e {41			pi!(@s; $o: $($then)*);42		}43		pi!(@s; $o: $($t)*);44	}};45	(@s; $o:ident: ifelse ($e:expr)($($then:tt)*)($($else:tt)*) $($t:tt)*) => {{46		if $e {47			pi!(@s; $o: $($then)*);48		} else {49			pi!(@s; $o: $($else)*);50		}51		pi!(@s; $o: $($t)*);52	}};53	(@s; $i:ident:) => {}54}55macro_rules! p {56	(new: $($t:tt)*) => {57		pi!(@i; $($t)*)58	};59	($o:ident: $($t:tt)*) => {60		pi!(@s; $o: $($t)*)61	};62}6364impl Printable for FieldName {65	fn print(&self) -> PrintItems {66		match self {67			FieldName::Fixed(f) => {68				p!(new: str(&f))69			}70			FieldName::Dyn(_) => todo!(),71		}72	}73}7475impl Printable for Visibility {76	fn print(&self) -> PrintItems {77		match self {78			Visibility::Normal => p!(new: str(":")),79			Visibility::Hidden => p!(new: str("::")),80			Visibility::Unhide => p!(new: str(":::")),81		}82	}83}8485impl Printable for BinaryOpType {86	fn print(&self) -> PrintItems {87		let o = self.to_string();88		p!(new: str(&o))89	}90}9192impl<T: Printable> Printable for Option<T> {93	fn print(&self) -> PrintItems {94		if let Some(v) = self {95			v.print()96		} else {97			PrintItems::new()98		}99	}100}101102impl Printable for Param {103	fn print(&self) -> PrintItems {104		p!(new:105			str(&self.0)106			if(self.1.is_some())(str(" = ") {self.1})107		)108	}109}110111impl Printable for ParamsDesc {112	fn print(&self) -> PrintItems {113		let mut out = PrintItems::new();114		for (i, item) in self.0.iter().enumerate() {115			if i != 0 {116				p!(out: str(", "));117			}118			out.extend(item.print());119		}120		out121	}122}123124impl Printable for ArgsDesc {125	fn print(&self) -> PrintItems {126		let mut out = PrintItems::new();127		let mut first = Some(());128		for u in self.unnamed.iter() {129			if first.take().is_none() {130				p!(out: str(", "));131			}132			p!(out: {u})133		}134		for (n, u) in self.named.iter() {135			if first.take().is_none() {136				p!(out: str(", "));137			}138			p!(out: str(&n) str(" = ") {u})139		}140141		out142	}143}144145impl Printable for BindSpec {146	fn print(&self) -> PrintItems {147		p!(new: str(&self.name) if(self.params.is_some())(str("(") {self.params} str(")")) str(" = ") {self.value})148	}149}150151struct StrExpr<'s>(&'s str);152153impl<'s> Printable for StrExpr<'s> {154	fn print(&self) -> PrintItems {155		todo!()156	}157}158159impl Printable for ObjBody {160	fn print(&self) -> PrintItems {161		let mut pi = PrintItems::new();162		p!(pi: str("{"));163		match self {164			ObjBody::MemberList(m) => {165				if !m.is_empty() {166					p!(pi: nl > i);167					for m in m {168						match m {169							Member::Field(f) => {170								p!(pi:171									{f.name} {f.params}172									if(f.plus)(str("+"))173									{f.visibility} str(" ")174									{f.value}175									str(",") nl176								);177							}178							Member::BindStmt(s) => {179								p!(pi: str("local ") {s} str(",") nl)180							}181							Member::AssertStmt(a) => p!(pi: str("assert ") {a.0} if(a.1.is_some())(182								str(" : ") {a.1}183							) str(",") nl),184						}185					}186					p!(pi: <i);187				} else {188					p!(pi: str(" "))189				}190			}191			ObjBody::ObjComp(_) => todo!(),192		}193		p!(pi: str("}"));194		pi195	}196}197198impl Printable for Expr {199	fn print(&self) -> PrintItems {200		let mut pi = PrintItems::new();201		match self {202			Expr::Literal(l) => match l {203				jrsonnet_parser::LiteralType::This => p!(pi: str("self")),204				jrsonnet_parser::LiteralType::Super => p!(pi: str("super")),205				jrsonnet_parser::LiteralType::Dollar => p!(pi: str("$")),206				jrsonnet_parser::LiteralType::Null => p!(pi: str("null")),207				jrsonnet_parser::LiteralType::True => p!(pi: str("true")),208				jrsonnet_parser::LiteralType::False => p!(pi: str("false")),209			},210			Expr::Str(s) => {211				p!(pi: str("\"") str(s) str("\""))212			}213			Expr::Num(n) => {214				let n = n.to_string();215				p!(pi: str(&n));216			}217			Expr::Var(v) => p!(pi: str(&v)),218			Expr::Arr(a) => {219				p!(pi: str("["));220				for (i, v) in a.iter().enumerate() {221					if i != 0 {222						p!(pi: str(", "));223					}224					p!(pi: {v})225				}226				p!(pi: str("]"));227			}228			Expr::ArrComp(_, _) => todo!(),229			Expr::Obj(o) => {230				p!(pi: {o});231			}232			Expr::ObjExtend(a, b) => p!(pi: {a} str(" ") {b}),233			Expr::Parened(v) => {234				if let Expr::Parened(_) = &v.0 as &Expr {235					p!(pi: {v})236				} else {237					p!(pi: str("(") {v} str(")"))238				}239			}240			Expr::UnaryOp(_, _) => todo!(),241			Expr::BinaryOp(a, o, b) => {242				p!(pi:243					{a} str(" ") if(!matches!(&b.0 as &Expr, Expr::Obj(_)))({o} str(" ")) {b}244				)245			}246			Expr::AssertExpr(_, _) => todo!(),247			Expr::LocalExpr(s, v) => {248				p!(pi:249					str("local") nl >i250				);251				for spec in s.iter() {252					p!(pi: {spec} str(";") nl)253				}254				p!(pi:255					<i256					{v}257				);258			}259			Expr::Import(i) => {260				let v = i.to_str().unwrap();261				p!(pi: str("import \"") str(&v) str("\""));262			}263			Expr::ImportStr(_) => todo!(),264			Expr::ErrorStmt(_) => todo!(),265			Expr::Apply(f, a, t) => p!(pi:266				{f} str("(") {a} str(")") if(*t)(str("tailstrict"))267			),268			Expr::Index(a, b) => p!(pi: {a} str("[") {b} str("]")),269			Expr::Function(_, _) => todo!(),270			Expr::Intrinsic(_) => todo!(),271			Expr::IfElse {272				cond,273				cond_then,274				cond_else,275			} => p!(pi:276				str("if ") {cond.0} str(" then") ifelse(cond_else.is_some())(277					nl >i278						{cond_then} nl279					<i str("else") nl >i280						{cond_else}281					<i282				)(str(" ") {cond_then})283			),284			Expr::Slice(v, d) => {285				p!(pi:286					{v}287					str("[") {d.start} str(":") {d.end}288					if(d.step.is_some())(289						str(":")290						{d.step}291					)292					str("]")293				)294			}295		}296		pi297	}298}299300impl Printable for LocExpr {301	fn print(&self) -> PrintItems {302		self.0.print()303	}304}305306fn main() {307	let parsed = jrsonnet_parser::parse(308		r#"309	310	311		# Edit me!312		local b = import "b.libsonnet";  # comment313		local a = import "a.libsonnet";314		315			 local f(x,y)=x+y;316		317		318		local Template = {z: "foo"};319		320		Template + {321						local322323					h = 3,324					assert self.a == 1325		  326					: "error",327		"f": ((((((3)))))) ,328		"g g":329		f(4,2),330		arr: [[331		  1, 2,332		  ],333		  3,334		  {335			  b: {336				  c: {337					  k: [16]338				  }339			  }340		  }341		  ],342		  m: a[1::],343		  m: b[::],344		  k: if a         == b    then 345346347		  2348349		  else Template {}350		}351		352	353"#,354		&ParserSettings {355			file_name: PathBuf::from("example").into(),356		},357	)358	.unwrap();359360	let o = dprint_core::formatting::format(361		|| {362			let print_items = parsed.print();363			print_items364		},365		PrintOptions {366			indent_width: 2,367			max_width: 100,368			use_tabs: false,369			new_line_text: "\n",370		},371	);372	println!("{}", o);373}