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

difftreelog

source

crates/nixlike/src/lib.rs3.0 KiBsourcehistory
1use linked_hash_map::LinkedHashMap;2use peg::str::LineCol;3use se_impl::MySerialize;4use serde::{Deserialize, Serialize};56mod de_impl;7mod se_impl;8mod to_string;910#[derive(thiserror::Error, Debug)]11pub enum Error {12	#[error("bad number")]13	BadNumber,14	#[error("expected {0}")]15	Expected(&'static str),16	#[error("parse error")]17	ParseError(#[from] peg::error::ParseError<LineCol>),18	#[error("{0}")]19	Custom(String),20	#[error("io: {0}")]21	Io(#[from] std::io::Error),22	#[error("fmt: {0}")]23	Fmt(#[from] std::fmt::Error),24}2526#[derive(Debug)]27pub enum Value {28	Number(i64),29	String(String),30	Boolean(bool),31	Object(LinkedHashMap<String, Value>),32	Array(Vec<Value>),33	Null,34}3536peg::parser! {37pub grammar nixlike() for str {38	rule number() -> i6439		= quiet! { v:$(['0'..='9' | '+' | '-']+) {? v.parse().map_err(|_| "<number>")} } / expected!("<number>")40	rule string_char() -> &'input str41		= "\\\"" { "\"" }42		/ "\\\\" { "\\" }43		/ c:$([_]) { c }44	rule string() -> String45		= quiet! { "\"" v:(!"\"" c:string_char() {c})* "\"" { v.into_iter().collect() } } / expected!("<string>")46	rule boolean() -> bool47		= quiet! { "true" {true}48		/ "false" {false} } / expected!("<boolean>")49	rule indent() -> String50		= quiet! { s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() } } / expected!("<identifier>")51	rule object() -> LinkedHashMap<String, Value>52		= "{" _53			e:(k:indent()++(_ "." _) _ "=" _ v:value() _ ";" _ {(k, v)})*54		"}" {?55			let mut out = LinkedHashMap::new();56			for (k, v) in e {57				let mut map = &mut out;58				for v in k.iter().take(k.len() - 1) {59					map = match map.entry(v.clone()).or_insert_with(|| Value::Object(Default::default())) {60						Value::Object(v) => v,61						_ => return Err("expected object"),62					}63				}6465				let key = k.into_iter().last().unwrap();66				if map.contains_key(&key) {67					return Err("can't override object");68				}69				map.insert(key, v);70			}71			Ok(out)72		}7374	rule array() -> Vec<Value>75		= "[" _ v:value()**_ _ "]" {v}7677	rule value() -> Value78		= o:object() { Value::Object(o) }79		/ a:array() { Value::Array(a) }80		/ s:string() { Value::String(s) }81		/ "null" { Value::Null }82		/ b:boolean() { Value::Boolean(b) }83		/ n:number() { Value::Number(n) }8485	pub rule root() -> Value86		= _ v:value() _ { v }8788	rule _()89		= ( quiet!{ [' ' | '\t' | '\n']+ }90		/ "#" (!['\n'] [_])* "\n" )*91}92}9394pub fn parse_str<'de, D: Deserialize<'de>>(s: &str) -> Result<D, Error> {95	let value = nixlike::root(s)?;96	D::deserialize(value)97}9899pub fn parse_value<'de, D: Deserialize<'de>>(value: Value) -> Result<D, Error> {100	D::deserialize(value)101}102103pub fn serialize_value_pretty(value: Value) -> String {104	to_string::write_nix(&value)105}106107pub fn serialize<S: Serialize>(value: S) -> Result<String, Error> {108	let value: Value = value.serialize(MySerialize)?;109	Ok(serialize_value_pretty(value))110}111112#[test]113fn test() {114	let v: serde_json::Value = parse_str(115		r#"116			{117				b.c = 2;118				b.d = "hello";119				c = {120					k = 123;121					p = 231;122					ll = [1 2 3 [] [[4 5 6]] ];123				};124			}125		"#,126	)127	.unwrap();128	let s: String = serialize(v).unwrap();129	println!("{}", s);130}