//! # Introduction
//!
//! **_Ciboulette_** is a **`JSON:API`** library.
//!
//! It allows one to parse request and build response respecting the `JSON:API`
//! [specifications](https://jsonapi.org/format/).
//!
//! It aims to have a low memory footprint and be **fast**.
//!
//! # High level view of components
//!
//! At a high level, an `API` is constitued of [resource types](CibouletteResourceType). The resource type are organized
//! in a graph representing their [relationships](CibouletteResourceRelationshipDetails) as edges.
//!
//! In addition to the graph, an adgacent map is used to efficiently retrieve [resource types](CibouletteResourceType)
//! by their alias. This whole structure is held in a [store](CibouletteStore).
//!
//! ## Resource types
//!
//! The [resource types](CibouletteResourceType) can be built using a [resource type builder](CibouletteResourceTypeBuilder).
//! It's made of :
//!
//! - A name, that will later be used as an alias to fetch the [resource types](CibouletteResourceType) from the [store](CibouletteStore)'s graph.
//! - A id type, which will be used to deserialize the ids the requests.
//! - A [schema](messy_json::MessyJsonObject) which will be used to deserialize the body of the requests and serialize the response.
//!
//! ## Relationship options
//!
//! ### Many-to-Many
//!
//! The [option struct](CibouletteRelationshipManyToManyOption) map a resource "A" to another resource "C" through another resource "B" (bucket)
//!
//! ```ascii
//! Resource A Resource B (bucket) Resource C
//! ┌─────────────────┐ ┌─────────────────────────────────────────────┐ ┌─────────────────┐
//! │ │ │ │ │ │
//! │ peoples──►id───┼──┼──►people_id◄──people-article──►article_id◄──┼──┼──id◄──articles │
//! │ │ │ │ │ │
//! └─────────────────┘ └─────────────────────────────────────────────┘ └─────────────────┘
//! ```
//!
//! When creating a Many-to-Many relationships (`A <-> C`), we'll also create a Many-to-One relationship between the table
//! `A -> B`, `C -> B`, `B -> A` and `B -> C` so that we can reference the relationship directly.
//!
//! ### One-to-Many / Many-to-One
//!
//! The [option struct](CibouletteRelationshipOneToManyOption) map a "many" resource to a "one" resource.
//!
//! ```ascii
//! Many table One table
//! ┌──────────────────────────────────────────────────┐ ┌──────────────────────────────────────┐
//! │ │ │ │
//! │ many_table_element_0──────────►many_table_key_0──┼──┼──►one_table_id◄───one_table_element │
//! │ │ │ ▲ ▲ │
//! │ │ │ │ │ │
//! │ many_table_element_1──────────►many_table_key_1──┼──┼─────┘ │ │
//! │ │ │ │ │
//! │ │ │ │ │
//! │ many_table_element_2──────────►many_table_key_2──┼──┼────────────┘ │
//! │ │ │ │
//! │ │ └──────────────────────────────────────┘
//! └──────────────────────────────────────────────────┘
//! ```
//!
//! In the option a field is used to determined if a Many-to-One/One-to-Many relationship is part of Many-to-Many relationship.
//!
//! ## Requests
//!
//! Every requests boils down to the same components. But there is some quirks :
//!
//! - Creation request can be valid without resource [id](CibouletteResourceIdentifierPermissive),
//! - Update request can have a body of [resource identifier](CibouletteResourceIdentifier).
//!
//! Every requests must first be deserialized using the [request builder](CibouletteRequestBuilder). Then it can be built
//! into an generic [request](CibouletteRequest). From that, one can convert to the desired request type depending on the
//! [intention](CibouletteIntention). Trying to convert a generic [request](CibouletteRequest) to an incompatible sub-type
//! will result in an [error](CibouletteError). The correct conversion map goes like this :
//!
//! | Intention | Request type |
//! |---------------------------------------|-------------------------------------------|
//! | [Create](CibouletteIntention::Create) | [Create request](CibouletteCreateRequest) |
//! | [Read](CibouletteIntention::Read) | [Read request](CibouletteReadRequest) |
//! | [Update](CibouletteIntention::Update) | [Update request](CibouletteUpdateRequest) |
//! | [Delete](CibouletteIntention::Delete) | [Delete request](CibouletteDeleteRequest) |
//!
//! Every sub-type of requests implement a [common trait](CibouletteRequestCommons) to allow for genericity.
//!
//! ## Responses
//!
//! A response is built from a [request](CibouletteRequestCommons) and a list of [response element](CibouletteResponseElement).
//!
//! Depending on the [request](CibouletteRequestCommons), the [response](CibouletteResponse) will be built to the correct format.
//!
//! ### Response elements
//!
//! Each response should have a single main [resource type](CibouletteResourceType).
//!
//!
//! The [response elements](CibouletteResponseElement) are composed as follow for an element part of the main [resource type](CibouletteResourceType):
//!
//! | Response element field | Always required | Description |
//! |------------------------|:------------------------------------------------------:|--------------------------------------------------------------------------------------|
//! | `type` | ✅ | The current element [resource type](CibouletteResourceType) |
//! | `identifier` | ✅ | The current element [resource identifier](CibouletteResourceIdentifier) |
//! | `data` | ❌ | The `JSON` data of the resource, if any |
//! | `related`.`rel_chain` | ❌<br />(only for related data) | Chain of relation metadata from the main [resource type](CibouletteResourceType) |
//! | `related`.`element` | ❌<br />(only for related data) | The [resource identifier](CibouletteResourceIdentifier) of the element it relates to |
//!
//!
//!
//!
//!
//!
//!
//!
use ArcStr;
use CibouletteResourceBuilderVisitor;
use ;
use *;
use ;
use Value;
use ;
use Cow;
use ;
use ;
use Arc;
use Url;
use Uuid;
pub use CibouletteOptionalData;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use CibouletteResourceTypeBuilder;
pub use ;
pub use CibouletteIntention;
pub use CibouletteResponse;
pub use CibouletteResponseStatus;
pub use ;
pub use CibouletteRequestSelector;
pub use CibouletteCreateRequest;
pub use CibouletteDeleteRequest;
pub use CibouletteReadRequest;
pub use ;
pub use ;
pub use CibouletteResponseElement;
pub use ;
pub use CibouletteResponseDataBuilder;
pub use CibouletteConfig;
pub use CibouletteErrorRequest;
pub use ;
pub use check_member_name;
pub use ;
pub use ;
pub use ;
pub use ;