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;