1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
//! # Yojson parser //! [![crates.io][crates-badge]][crates] //! [![docs.rs][docs-badge]][docs] //! [![Build Status][ci-badge]][ci] //! [![source badge][source-badge]][source] //! [![license badge][license-badge]][license] //! //! [crates]: https://crates.io/crates/yojson-rs //! [crates-badge]: https://img.shields.io/crates/v/yojson-rs //! [docs]: https://docs.rs/yojson-rs/ //! [docs-badge]: https://img.shields.io/badge/docs.rs-yojson_rs-blue //! [ci]: https://github.com/puripuri2100/yojson-rs/actions?query=workflow%3ACI //! [ci-badge]: https://github.com/puripuri2100/yojson-rs/workflows/CI/badge.svg?branch=master //! [source]: https://github.com/puripuri2100/yojson-rs //! [source-badge]: https://img.shields.io/badge/source-github-blue //! [license]: https://github.com/puripuri2100/yojson-rs/blob/master/LICENSE //! [license-badge]: https://img.shields.io/badge/license-MIT-blue //! //! This library parses [JSON data (yojson format)](https://mjambon.github.io/mjambon2016/yojson.html) into a nested Rust tree data structure. //! //! # Yojson values //! //! A value in Yojson is represented with the `Value` enum in this crate: //! //! ```ignore //! pub enum Value { //! Null, //! Bool(bool), //! Integer(i64), //! Float(f64), //! String(String), //! Assoc(Assoc), //! Array(Array), //! Tuple(Vec<Value>), //! Variant(Variant), //! } //! ``` //! //! The Yojson format is an extension of the JSON format. See ["Yojson format document"](https://mjambon.github.io/mjambon2016/yojson.html) for more information. //! - Tuples: like JSON arrays but within parentheses instead of square brackets, such as `(1.23, 4.56)`. //! - Variants without argument: `<"Foo">`. //! - Variants with one argument: `<"Bar": 123>`. //! - Unquoted field names and variants are accepted if they match the pattern `[A-Za-z][A-Za-z_0-9]*`: `{ x: <Foo>, "#y": <Bar2> }`. //! - Comments: `/* multiline comment */` and `// end-of-line comment`. //! - Special numeric entities: `[ Infinity, -Infinity, NaN ]`. //! //! # Parsing JSON //! //! Parse JSON data. //! //! ```ignore //! use yojson_rs; //! //! # fn main () { //! let json = r#" //! { //! x : 123, //! y : { //! "y1" : "abc\ndef\u0021", //! "y2" : [null, 123.45, (12, "y3")] //! }, //! z : NaN //! } //! "#; //! assert!(yojson_rs::parser::parse(json).is_ok()); //! # } //! //! ``` //! //! # Convert to a JSON string. //! A data structure can be converted to a JSON string by `to_string`. //! //! ```ignore //! use yojson_rs; //! //! # fn main() { //! let json_str = r#" //! { //! x : 123, //! y : { //! "y1" : "abc\ndef\u0021", //! "y2" : [null, 123.45, (12, "y3")] //! }, //! z : NaN //! } //! "#; //! let json = yojson_rs::parser::parse(json_str).unwrap(); //! println!("{}", yojson_rs::to_string(json)); //! # } //! ``` extern crate pest; #[macro_use] extern crate pest_derive; pub mod parser; pub mod value; /// Convert to a JSON string. pub fn to_string(value: value::Value) -> String { match value { value::Value::Null => "null".to_string(), value::Value::Bool(b) => b.to_string(), value::Value::Integer(i) => i.to_string(), value::Value::Float(f) => f.to_string(), value::Value::String(s) => format!("{:?}", s), value::Value::Assoc(assoc) => { let mut s = String::new(); for (i, item) in assoc.iter().enumerate() { let (name, value) = item; if i == 0 { s.push_str(&format!("{}:{}", name, to_string(value.clone()))) } else { s.push_str(&format!(",{}:{}", name, to_string(value.clone()))) } } format!("{{{}}}", s) } value::Value::Array(array) => { let mut s = String::new(); for (i, item) in array.iter().enumerate() { if i == 0 { s.push_str(&to_string(item.clone())) } else { s.push_str(&format!(",{}", to_string(item.clone()))) } } format!("[{}]", s) } value::Value::Tuple(tuple) => { let mut s = String::new(); for (i, item) in tuple.iter().enumerate() { if i == 0 { s.push_str(&to_string(item.clone())) } else { s.push_str(&format!(",{}", to_string(item.clone()))) } } format!("({})", s) } value::Value::Variant(variant) => { let (name, value_opt) = variant; match value_opt { None => format!("<{}>", name), Some(value) => format!("<{}:{}>", name, to_string(*value)), } } } }