git.delta.rocks / jrsonnet / refs/commits / 6ca3e00a2ff9

difftreelog

feat parse null

Yaroslav Bolyukin2021-09-18parent: #8deb0df.patch.diff
in: trunk

1 file changed

modifiedcrates/nixlike/src/lib.rsdiffbeforeafterboth
after · crates/nixlike/src/lib.rs
1use std::collections::BTreeMap;23use peg::str::LineCol;4use se_impl::MySerialize;5use serde::{Deserialize, Serialize};67mod de_impl;8mod se_impl;9mod to_string;1011#[derive(thiserror::Error, Debug)]12pub enum Error {13	#[error("bad number")]14	BadNumber,15	#[error("expected {0}")]16	Expected(&'static str),17	#[error("parse error")]18	ParseError(#[from] peg::error::ParseError<LineCol>),19	#[error("{0}")]20	Custom(String),21	#[error("io: {0}")]22	Io(#[from] std::io::Error),23	#[error("fmt: {0}")]24	Fmt(#[from] std::fmt::Error),25}2627#[derive(Debug)]28pub enum Value {29	Number(i64),30	String(String),31	Boolean(bool),32	Object(BTreeMap<String, Value>),33	Array(Vec<Value>),34	Null,35}3637peg::parser! {38pub grammar nixlike() for str {39	rule number() -> i6440		= v:$(['0'..='9' | '+' | '-']+) {? v.parse().map_err(|_| "<number>")}41	rule string() -> String42		= "\"" v:$((!"\"" [_])+) "\"" { v.to_owned() }43	rule boolean() -> bool44		= "true" {true}45		/ "false" {false}46	rule indent() -> String47		= s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() }48	rule object() -> BTreeMap<String, Value>49		= "{" _50			e:(k:indent()++(_ "." _) _ "=" _ v:value() _ ";" _ {(k, v)})*51		"}" {?52			let mut out = BTreeMap::new();53			for (k, v) in e {54				let mut map = &mut out;55				for v in k.iter().take(k.len() - 1) {56					map = match map.entry(v.clone()).or_insert_with(|| Value::Object(Default::default())) {57						Value::Object(v) => v,58						_ => return Err("expected object"),59					}60				}6162				let key = k.into_iter().last().unwrap();63				if map.contains_key(&key) {64					return Err("can't override object");65				}66				map.insert(key, v);67			}68			Ok(out)69		}7071	rule array() -> Vec<Value>72		= "[" _ v:value()**_ _ "]" {v}7374	rule value() -> Value75		= o:object() { Value::Object(o) }76		/ a:array() { Value::Array(a) }77		/ s:string() { Value::String(s) }78		/ "null" { Value::Null }79		/ b:boolean() { Value::Boolean(b) }80		/ n:number() { Value::Number(n) }8182	pub rule root() -> Value83		= _ v:value() _ { v }8485	rule _()86		= ( quiet!{ [' ' | '\t' | '\n']+ }87		/ "#" (!['\n'] [_])* "\n" )*88}89}9091pub fn parse_str<'de, D: Deserialize<'de>>(s: &str) -> Result<D, Error> {92	let value = nixlike::root(s)?;93	D::deserialize(value)94}9596pub fn parse_value<'de, D: Deserialize<'de>>(value: Value) -> Result<D, Error> {97	D::deserialize(value)98}99100pub fn serialize_value_pretty(value: Value) -> Result<String, Error> {101	to_string::write_nix(&value)102}103104pub fn serialize<S: Serialize>(value: S) -> Result<String, Error> {105	let value: Value = value.serialize(MySerialize)?;106	serialize_value_pretty(value)107}108109#[test]110fn test() {111	let v: serde_json::Value = parse_str(112		r#"113			{114				b.c = 2;115				b.d = "hello";116				c = {117					k = 123;118					p = 231;119					ll = [1 2 3 [] [[4 5 6]] ];120				};121			}122		"#,123	)124	.unwrap();125	let s: String = serialize(v).unwrap();126	println!("{}", s);127}