JSOxideN is a JSON serialiser and deserialiser written in Rust, created as a personal learning exercise to deepen my understanding of traits, macros, and procedural macros. The project leverages the syn and proc_macro crates to handle the serialisation and deserialisation of any Rust struct with named fields to and from JSON data.
- Traits: Implemented derivable traits using procedural macros for JSON serialisation and deserialisation. Ensuring that implementations work within Rust's orphan rules.
- Procedural macros with syn and proc_macro crates: Used the
syncrate for parsing Rust code and theproc_macrocrate for creating procedural macros leveraging the syntax trees generated bysynto automatically derive serialisation and deserilisation implementations. - Macro usage: Utilized Rust macros to reduce boilerplate by generating code.
- Automatic test generation: Used
build.rsto automatically generate tests based on the files provided by the JSONTestSuite.
The library can be used with the inbuilt Value type that represents the types specified by JSON. A variety of helpful methods are provided for manipulating and accessing the Value type and a keys of a JSON object can be accessed using the standard index operator.
For easier usage the library also allows strong typing through structs, allowing the user to define a struct and automatically derive a deserialisation implementation.
Any struct with compatible named fields can also derive a serialisation implementation to convert an instance to a JSON string.
Deserialisation and serialisation implementations are already provided for all signed and unsigned integers (excluding usize and isize), the floating point types, characters, strings, and vectors. Option<T> is also supported and objects are represented with IndexMap.
IndexMap allows JSON objects to be stored and then output in the order they were consumed either from a JSON string or from a struct.
The provided derive macro can be used to implement deserialisation for structs:
use jsoxiden::Deserialise;
#[derive(Deserialise)]
struct MyStruct {
field1: String,
field2: i32,
}
let json_data = r#"
{
"field1": "value",
"field2": 42
}
"#;
let my_struct = MyStruct::from_str(json_data).unwrap();Serialisation can then be used as follows:
use jsoxiden::{Deserialise, Serialise};
#[derive(Deserialise, Serialise)]
struct MyStruct {
field1: String,
field2: i32,
}
let json_data = r#"
{
"field1": "value",
"field2": 42
}
"#;
let my_struct = MyStruct::from_str(json_data).unwrap();
println!("{}", my_struct.to_json_string());This project is licensed under the MIT License. See the LICENSE file for details.
This project represents a personal educational journey into areas of Rust I had not previously been exposed to, further pushing the boundaries of my knowledge and skills with the language.