native_json_macro/lib.rs
1//!# Native JSON for Rust
2//!
3//!This crate provides native JSON syntax for Rust, it brings with a powerful way of parsing JSON syntax into native Rust structs. You can declare the JSON object natively as you do with JavaScript, JSON in Rust was made easy!
4//!
5//!> Note: This crate is just a crude proc-macro (compiler plugin), for more features, please refer to [native-json](https://crates.io/crates/native-json)
6//!
7//!## Usage
8//!Add dependencies to your Cargo.toml, `serde_json` is only needed if you want to stringify the JSON object.
9//!```toml
10//![dependencies]
11//!native-json = "1.2"
12//!serde = {version = "1.0", features = ["derive"] }
13//!serde_json = "1.0"
14//!```
15//!
16//!## Example of using native JSON object
17//!```rust
18//!use native_json::json;
19//!use std::collections::HashMap;
20//!use serde::{Deserialize, Serialize};
21//!
22//!fn main()
23//!{
24//! let mut json = json!{
25//! name: "native json",
26//! style: {
27//! color: "red",
28//! size: 12,
29//! bold: true,
30//! range: null
31//! },
32//! array: [5,4,3,2,1],
33//! vector: vec![1,2,3,4,5],
34//! hashmap: HashMap::from([ ("a", 1), ("b", 2), ("c", 3) ]);,
35//! students: [
36//! {name: "John", age: 18},
37//! {name: "Jack", age: 21},
38//! ],
39//! };
40//!
41//! // Native access
42//! json.style.size += 1;
43//! json.students[0].age += 2;
44//!
45//! // Debug
46//! println!("{:#?}", t);
47//!
48//! // Stringify
49//! let text = json.string().unwrap();
50//! println!("{}", text);
51//!}
52//!```
53//!## Declare a named JSON struct
54//!
55//!With JSON declare syntax, you can declare nested native JSON object in place.
56//!Note: Identifier with underscore suffix will be renamed when serialize and deserialize, `type_` will be renamed to `type`.
57//!
58//!### JSON Declare Syntax
59//!```rust
60//!json!{
61//!JSON_OBJECT_NAME {
62//! name : type,
63//! value: type?, // optional field when serialize & deserialize
64//! type_: String, // suffix underscore will be removed when serialize & deserialize
65//! array: [type],
66//! object: {
67//! name: type,
68//! ...
69//! },
70//! ...
71//!}}
72//!```
73//!
74//!The native-json will generate native Rust structs for you, each object is named by object hierarchy path, concatenated with underscore.
75//!
76//! 1. `JSON_OBJECT_NAME.object` was converted to `JSON_OBJECT_NAME_object`
77//! 2. `JSON_OBJECT_NAME.array's item` was converted to `JSON_OBJECT_NAME_array_item`
78//!
79//!## Example of using named JSON object
80//!
81//!```rust
82//!use native_json::json;
83//!use serde::{Deserialize, Serialize};
84//!use std::collections::HashMap;
85//!
86//!json!{
87//!School {
88//! name: String,
89//! rank: u32?, // optional
90//! students: [
91//! { name: String, age: u16 },
92//! ...
93//! ],
94//! map: HashMap<String, String>,
95//! nullable: Option<String>
96//!}}
97//!
98//!fn main()
99//!{
100//! let mut school = School::new();
101//!
102//! school.name = "MIT".to_string();
103//! school.map.insert("Tom".to_owned(), "Profile".to_owned());
104//!
105//! // using initializer
106//! let mut john = School_students_item::new();
107//! john.name = "John".to_owned();
108//! john.age = 18;
109//! school.students.push(john);
110//!
111//! // using struct
112//! let jack = School_students_item { name: "Jack".to_string(), age: 21 };
113//! school.students.push(jack);
114//!
115//! // show
116//! println!("{:#?}", school);
117//!}
118//!```
119//!
120extern crate proc_macro;
121mod json;
122
123use json::*;
124use proc_macro::TokenStream;
125use std::str::FromStr;
126use syn::parse_macro_input;
127
128/// Declare or instantiate a native JSON object, please refere to module [json](index.html)
129#[proc_macro]
130pub fn json(input: TokenStream) -> TokenStream {
131 let parser = parse_macro_input!(input as Json);
132 let block = parser.get_block();
133 // Show me the code
134 // println!("XXXXXXXXXXXXXXXX\n{}", block);
135 return TokenStream::from_str(block.as_str()).unwrap();
136}