jsonapi/lib.rs
1#![deny(missing_debug_implementations,
2 missing_copy_implementations,
3 trivial_casts,
4 trivial_numeric_casts,
5 unsafe_code,
6 unstable_features,
7 unused_import_braces,
8 unused_qualifications
9 )]
10
11#![doc(html_root_url = "https://docs.rs/jsonapi/")]
12
13//! This is documentation for the `jsonapi` crate.
14//! The crate is meant to be used for serializing, deserializing and validating
15//! [JSON:API] requests and responses.
16//!
17//! [JSON:API]: https://jsonapi.org/
18//! [serde]: https://serde.rs
19//! [JsonApiDocument]: api/struct.JsonApiDocument.html
20//! [Resource]: api/struct.Resource.html
21//! [jsonapi_model]: macro.jsonapi_model.html
22//!
23//! ## Examples
24//!
25//! ### Basic Usage with Macro
26//!
27//! Using the [`jsonapi_model!`][jsonapi_model] macro a struct can be converted
28//! into a [`JsonApiDocument`][JsonApiDocument] or [`Resource`][Resource]. It is
29//! required that the struct have an `id` property whose type is `String`. The
30//! second argument in the [`jsonapi_model!`][jsonapi_model] marco defines the
31//! `type` member as required by the [JSON:API] specification
32//!
33//! ```rust
34//! #[macro_use] extern crate serde_derive;
35//! #[macro_use] extern crate jsonapi;
36//! use jsonapi::api::*;
37//! use jsonapi::model::*;
38//!
39//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
40//! struct Flea {
41//! id: String,
42//! name: String,
43//! };
44//!
45//! jsonapi_model!(Flea; "flea");
46//!
47//! let example_flea = Flea {
48//! id: "123".into(),
49//! name: "Mr.Flea".into(),
50//! };
51//!
52//! // Convert into a `JsonApiDocument`
53//! let doc = example_flea.to_jsonapi_document();
54//! assert!(doc.is_valid());
55//!
56//! // Convert into a `Resource`
57//! let resource = example_flea.to_jsonapi_resource();
58//! ```
59//!
60//! ### Deserializing a JSON:API Document
61//!
62//! Deserialize a JSON:API document using [serde] by explicitly declaring the
63//! variable type in `Result`
64//!
65//! ```rust
66//! let serialized = r#"
67//! {
68//! "data": [{
69//! "type": "articles",
70//! "id": "1",
71//! "attributes": {
72//! "title": "JSON:API paints my bikeshed!",
73//! "body": "The shortest article. Ever."
74//! },
75//! "relationships": {
76//! "author": {
77//! "data": {"id": "42", "type": "people"}
78//! }
79//! }
80//! }],
81//! "included": [
82//! {
83//! "type": "people",
84//! "id": "42",
85//! "attributes": {
86//! "name": "John"
87//! }
88//! }
89//! ]
90//! }"#;
91//! let data: Result<Resource, serde_json::Error> = serde_json::from_str(&serialized);
92//! assert_eq!(data.is_ok(), true);
93//! ```
94//!
95//! Or parse the `String` directly using the
96//! [Resource::from_str](api/struct.Resource.html) trait implementation
97//!
98//! ```rust
99//! let data = Resource::from_str(&serialized);
100//! assert_eq!(data.is_ok(), true);
101//! ```
102//!
103//! [`JsonApiDocument`][JsonApiDocument] implements `PartialEq` which allows two
104//! documents to be compared for equality. If two documents possess the **same
105//! contents** the ordering of the attributes and fields within the JSON:API
106//! document are irrelevant and their equality will be `true`.
107//!
108//! ## Testing
109//!
110//! Run the tests:
111//!
112//! ```text
113//! cargo test
114//! ```
115//!
116//! Run tests with more verbose output:
117//!
118//! ```text
119//! RUST_BACKTRACE=1 cargo test -- --nocapture
120//! ```
121//!
122//! Run tests whenever files are modified using `cargo watch`:
123//!
124//! ```text
125//! RUST_BACKTRACE=1 cargo watch "test -- --nocapture"
126//! ```
127//!
128
129extern crate serde;
130extern crate serde_json;
131#[macro_use]
132extern crate serde_derive;
133
134extern crate queryst;
135
136#[macro_use]
137extern crate log;
138
139#[macro_use]
140extern crate error_chain;
141
142pub mod api;
143pub mod array;
144pub mod query;
145pub mod model;
146pub mod errors;