#![forbid(unsafe_code)]
pub mod ast;
pub mod error;
pub mod format;
pub mod scanner;
pub mod validate;
use std::fmt::Write;
pub use error::Error;
use scanner::Scanner;
pub fn to_jsonc(input: &str) -> Result<String, Error> {
let mut out = String::with_capacity(input.len() + 128);
to_jsonc_writer(&mut out, input)?;
Ok(out)
}
pub fn to_jsonc_writer<W: Write>(w: &mut W, input: &str) -> Result<(), Error> {
let root = ast::parse(input)?;
format::write_jsonc(w, &root)?;
Ok(())
}
pub fn to_json(input: &str) -> Result<String, Error> {
let mut out = String::with_capacity(input.len() + 128);
to_json_writer(&mut out, input)?;
Ok(out)
}
pub fn to_json_writer<W: Write>(w: &mut W, input: &str) -> Result<(), Error> {
let root = ast::parse_iter(Scanner::new(input).without_metadata())?;
format::write_jsonc(w, &root)?;
Ok(())
}
pub fn to_json_compact(input: &str) -> Result<String, Error> {
let mut out = String::with_capacity(input.len());
to_json_writer_compact(&mut out, input)?;
Ok(out)
}
pub fn to_json_writer_compact<W: Write>(w: &mut W, input: &str) -> Result<(), Error> {
format::write_json_compact_iter(w, Scanner::new(input).without_metadata())?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = r#"
// This is a comment.
// Second line.
// Break, than third.
{ // Object start.
"key1": "val1", // Same line comment.
"k": "v",
// Next line comment.
"arr_key": [ // Array start.
"val1"
,
100 // Before comma
,
// True.
true,
],
// And another.
"key2": { "nested": // And another one.
100, "value": true, "third": "this"
// Weird comment before comma.
, "is": "a", "v":{"another" :"object", } },
} // Trailing comment."#;
#[test]
fn test_to_jsonc() {
let expected = r#"// This is a comment.
// Second line.
// Break, than third.
{
// Object start.
"key1": "val1", // Same line comment.
"k": "v",
// Next line comment.
"arr_key": [
// Array start.
"val1",
100, // Before comma
// True.
true
],
// And another.
"key2": {
// And another one.
"nested": 100,
"value": true,
"third": "this",
// Weird comment before comma.
"is": "a",
"v": { "another": "object" }
}
} // Trailing comment.
"#;
let out = to_jsonc(INPUT).unwrap();
assert_eq!(&out, expected);
let out2 = to_jsonc(&out).unwrap();
assert_eq!(&out2, &out);
}
#[test]
fn test_to_json() {
let expected = r#"{
"key1": "val1",
"k": "v",
"arr_key": ["val1", 100, true],
"key2": {
"nested": 100,
"value": true,
"third": "this",
"is": "a",
"v": { "another": "object" }
}
}
"#;
let out = to_json(INPUT).unwrap();
assert_eq!(&out, expected);
let out2 = to_json(&out).unwrap();
assert_eq!(&out2, &out);
let _: serde_json::Value = serde_json::from_str(&out).expect("unable to parse json output");
}
#[test]
fn test_to_json_compact() {
let expected = r#"{"key1":"val1","k":"v","arr_key":["val1",100,true],"key2":{"nested":100,"value":true,"third":"this","is":"a","v":{"another":"object"}}}"#;
let out = to_json_compact(INPUT).unwrap();
assert_eq!(&out, expected);
let out2 = to_json_compact(&out).unwrap();
assert_eq!(&out2, &out);
let _: serde_json::Value = serde_json::from_str(&out).expect("unable to parse json output");
}
}