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 / "\\n" { "\n" }44 / "\\t" { "\t" }45 / "\\r" { "\r" }46 / "''$" { "$" }47 / c:$([_]) { c }48 rule string() -> String49 = quiet! { "\"" v:(!"\"" c:string_char() {c})* "\"" { v.into_iter().collect() } } / expected!("<string>")50 rule boolean() -> bool51 = quiet! { "true" {true}52 / "false" {false} } / expected!("<boolean>")53 rule indent() -> String54 = quiet! {55 s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-']+) { s.to_owned() }56 / "\"" s:$(['a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '-' | '.']+) "\"" { s.to_owned() }57 } / expected!("<identifier>")58 rule object() -> LinkedHashMap<String, Value>59 = "{" _60 e:(k:indent()++(_ "." _) _ "=" _ v:value() _ ";" _ {(k, v)})*61 "}" {?62 let mut out = LinkedHashMap::new();63 for (k, v) in e {64 let mut map = &mut out;65 for v in k.iter().take(k.len() - 1) {66 map = match map.entry(v.clone()).or_insert_with(|| Value::Object(Default::default())) {67 Value::Object(v) => v,68 _ => return Err("expected object"),69 }70 }7172 let key = k.into_iter().last().unwrap();73 if map.contains_key(&key) {74 return Err("can't override object");75 }76 map.insert(key, v);77 }78 Ok(out)79 }8081 rule array() -> Vec<Value>82 = "[" _ v:value()**_ _ "]" {v}8384 rule value() -> Value85 = o:object() { Value::Object(o) }86 / a:array() { Value::Array(a) }87 / s:string() { Value::String(s) }88 / "null" { Value::Null }89 / b:boolean() { Value::Boolean(b) }90 / n:number() { Value::Number(n) }9192 pub rule root() -> Value93 = _ v:value() _ { v }9495 rule _()96 = ( quiet!{ [' ' | '\t' | '\n']+ }97 / "#" (!['\n'] [_])* "\n" )*98}99}100101pub fn parse_str<'de, D: Deserialize<'de>>(s: &str) -> Result<D, Error> {102 let value = nixlike::root(s)?;103 D::deserialize(value)104}105106pub fn parse_value<'de, D: Deserialize<'de>>(value: Value) -> Result<D, Error> {107 D::deserialize(value)108}109110pub fn serialize_value_pretty(value: Value) -> String {111 to_string::write_nix(&value)112}113114pub fn serialize<S: Serialize>(value: S) -> Result<String, Error> {115 let value: Value = value.serialize(MySerialize)?;116 Ok(serialize_value_pretty(value))117}118119#[test]120fn test() {121 assert_eq!(serialize("Hello\nworld").unwrap(), "\"Hello\\nworld\"");122}