difftreelog
feat parse null
in: trunk
1 file changed
crates/nixlike/src/lib.rsdiffbeforeafterboth1use 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 / b:boolean() { Value::Boolean(b) }79 / n:number() { Value::Number(n) }8081 pub rule root() -> Value82 = _ v:value() _ { v }8384 rule _()85 = ( quiet!{ [' ' | '\t' | '\n']+ }86 / "#" (!['\n'] [_])* "\n" )*87}88}8990pub fn parse_str<'de, D: Deserialize<'de>>(s: &str) -> Result<D, Error> {91 let value = nixlike::root(s)?;92 D::deserialize(value)93}9495pub fn parse_value<'de, D: Deserialize<'de>>(value: Value) -> Result<D, Error> {96 D::deserialize(value)97}9899pub fn serialize_value_pretty(value: Value) -> Result<String, Error> {100 to_string::write_nix(&value)101}102103pub fn serialize<S: Serialize>(value: S) -> Result<String, Error> {104 let value: Value = value.serialize(MySerialize)?;105 serialize_value_pretty(value)106}107108#[test]109fn test() {110 let v: serde_json::Value = parse_str(111 r#"112 {113 b.c = 2;114 b.d = "hello";115 c = {116 k = 123;117 p = 231;118 ll = [1 2 3 [] [[4 5 6]] ];119 };120 }121 "#,122 )123 .unwrap();124 let s: String = serialize(v).unwrap();125 println!("{}", s);126}