JsonWay gives you a simple DSL for declaring JSON structures. This is particularly helpful when the generation process is fraught with conditionals and loops. It is inspired by jbuilder and has similar functionality.
# Cargo.toml
[dependencies.jsonway]
git = "https://github.com/rustless/jsonway"jsonway::object(|json| {
json.set("first_name","Luke".to_string());
json.set("last_name","Skywalker".to_string());
json.object("info", |json| {
json.set("homeworld","Tatooine".to_string());
json.set("born","19 BBY".to_string());
json.set("died","Between 45 ABY and 137 ABY".to_string());});
json.array("masters", |json| {
json.push("Obi-Wan Kenobi".to_string());
json.push("Yoda".to_string());
json.push("Joruus C'baoth (Briefly)".to_string());
json.push("Darth Sidious (Briefly)".to_string());});});// {// "first_name": "Luke",// "last_name": "Skywalker",// "info": {// "born": "19 BBY",// "died": "Between 45 ABY and 137 ABY",// "homeworld": "Tatooine"// },// "masters": [// "Obi-Wan Kenobi",// "Yoda",// "Joruus C'baoth (Briefly)",// "Darth Sidious (Briefly)"// ]// }#[derive(Debug)]enumSide{Light,Dark}structJedi{name:String,side:Side}let jedi = vec![Jedi{ name:"Saes Rrogon".to_string(), side:Side::Dark},Jedi{ name:"Qui-Gon Jinn".to_string(), side:Side::Light},Jedi{ name:"Obi-Wan Kenobi".to_string(), side:Side::Light}];let light_jedi_objects_list = jsonway::array(|json| {// Use `objects` method to make list of objects
json.objects(&mut jedi.iter(), |jedi, json| {match jedi.side{Side::Light => {
json.set("name".to_string(), jedi.name.to_string());
json.set("side".to_string(),format!("{:?}", jedi.side));}Side::Dark => json.skip(),}})});// [// {// "name": "Qui-Gon Jinn",// "side": "Light"// },// {// "name": "Obi-Wan Kenobi",// "side": "Light"// }// ]let light_jedi_tuple_list = jsonway::array(|json| {// Use `arrays` method to make list of lists
json.arrays(&mut jedi.iter(), |jedi, json| {match jedi.side{Side::Light => {
json.push(jedi.name.to_string());
json.push(format!("{:?}", jedi.side));}Side::Dark => json.skip(),}})});// [// [// "Qui-Gon Jinn",// "Light"// ],// [// "Obi-Wan Kenobi",// "Light"// ]// ]You can explicitly make JsonWay object return null if you want:
// ..match jedi.side{Side::Light => {
json.push(jedi.name.to_string());
json.push(format!("{:?}", jedi.side));},Side::Dark => json.null()}Provides convention and functionality to create custom JSON presenters for any struct.
use jsonway::{ObjectBuilder,Serializer};structJedi{name:String}structJediSerializer<'a>{jedi:&'aJedi}impl<'a>SerializerforJediSerializer<'a>{fnroot(&self) -> Option<&str>{Some("jedi")}fnbuild(&self,json:&mutObjectBuilder){
json.set("name",self.jedi.name.to_string());}}let jedi = Jedi{name:"Saes Rrogon".to_string()};let json = JediSerializer{jedi:&jedi}.serialize();ObjectSerializer<T> is a generic struct for single object:T serialization.
use jsonway::{ObjectBuilder,ObjectSerializer};structJedi{name:String}structJediSerializer;implObjectSerializer<Jedi>forJediSerializer{fnroot(&self) -> Option<&str>{Some("jedi")}fnbuild(&self,jedi:&Jedi,json:&mutObjectBuilder){
json.set("name", jedi.name.to_string());}}let jedi = Jedi{name:"Saes Rrogon".to_string()};let json = JediSerializer.serialize(&jedi);ObjectScopeSerializer<T, S> is a generic struct for object:T and scope:S serialization.
use jsonway::{ObjectBuilder,ObjectScopeSerializer};structUser{id:uint,is_admin:bool}structJedi{name:String,secret:String}structJediSerializer;implObjectScopeSerializer<Jedi,User>forJediSerializer{fnroot(&self) -> Option<&str>{Some("jedi")}fnbuild(&self,jedi:&Jedi,current_user:&User,json:&mutObjectBuilder){
json.set("name", jedi.name.to_string());if current_user.is_admin{
json.set("secret", jedi.secret.to_string());}}}let jedi = Jedi{name:"Palpatine".to_string(),secret:"Dark side".to_string()};let current_user = User{id:1,is_admin:true};let json = JediSerializer.serialize(&jedi,¤t_user);Provides convention and functionality to create custom JSON presenters for the list of resources including meta information.
TODO: Example