/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Note: If you change this remember to update `README.md`. To do so run `./tools/update-readme.sh`.
//! # Archery
//!
//! Archery is a rust library that offers a way to abstraction over
//! [`Rc`](alloc::rc::Rc) and
//! [`Arc`](alloc::sync::Arc) smart pointers.
//! This allows you to create data structures where the pointer type is parameterizable, so you can
//! [avoid the overhead of `Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety)
//! when you don’t need to share data across threads.
//!
//! In languages that supports
//! [higher-kinded polymorphism](https://en.wikipedia.org/wiki/Type_class#Higher-kinded_polymorphism)
//! this would be simple to achieve without any library, but
//! [rust does not support that yet](https://github.com/rust-lang/rfcs/issues/324).
//! To mimic higher-kinded polymorphism Archery implements the approach suggested by
//! Joshua Liebow-Feeser in
//! “[Rust has higher kinded types already… sort of](https://joshlf.com/post/2018/10/18/rust-higher-kinded-types-already/)”.
//! While [other approaches](#alternative-approaches) exist, they seem to always offer poor
//! ergonomics for the user.
//!
//! ## Setup
//!
//! To use Archery add the following to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! archery = "<version>"
//! ```
//!
//! ## Using Archery
//!
//! Archery defines a [`SharedPointer`]
//! that receives the [kind of pointer](SharedPointerKind)
//! as a type parameter. This gives you a convenient and ergonomic way to abstract the pointer
//! type away.
//!
//! ### Example
//!
//! Declare a data structure with the pointer kind as a type parameter bounded by
//! [`SharedPointerKind`]:
//!
//! ```rust
//! use archery::*;
//!
//! struct KeyValuePair<K, V, P: SharedPointerKind> {
//! pub key: SharedPointer<K, P>,
//! pub value: SharedPointer<V, P>,
//! }
//!
//! impl<K, V, P: SharedPointerKind> KeyValuePair<K, V, P> {
//! fn new(key: K, value: V) -> KeyValuePair<K, V, P> {
//! KeyValuePair {
//! key: SharedPointer::new(key),
//! value: SharedPointer::new(value),
//! }
//! }
//! }
//! ```
//!
//! To use it just plug-in the kind of pointer you want:
//!
//! ```rust
//! # /*DROP_LINE_IN_README*/ use archery::*;
//! # /*DROP_LINE_IN_README*/
//! # /*DROP_LINE_IN_README*/ struct KeyValuePair<K, V, P: SharedPointerKind> {
//! # /*DROP_LINE_IN_README*/ pub key: SharedPointer<K, P>,
//! # /*DROP_LINE_IN_README*/ pub value: SharedPointer<V, P>,
//! # /*DROP_LINE_IN_README*/ }
//! # /*DROP_LINE_IN_README*/
//! # /*DROP_LINE_IN_README*/ impl<K, V, P: SharedPointerKind> KeyValuePair<K, V, P> {
//! # /*DROP_LINE_IN_README*/ fn new(key: K, value: V) -> KeyValuePair<K, V, P> {
//! # /*DROP_LINE_IN_README*/ KeyValuePair {
//! # /*DROP_LINE_IN_README*/ key: SharedPointer::new(key),
//! # /*DROP_LINE_IN_README*/ value: SharedPointer::new(value),
//! # /*DROP_LINE_IN_README*/ }
//! # /*DROP_LINE_IN_README*/ }
//! # /*DROP_LINE_IN_README*/ }
//! # /*DROP_LINE_IN_README*/
//! let pair: KeyValuePair<_, _, RcK> =
//! KeyValuePair::new("António Variações", 1944);
//!
//! assert_eq!(*pair.value, 1944);
//! ```
//!
//! ## Limitations
//!
//! Currently it is not possible to have unsized types inside a [`SharedPointer`]. As a workaround
//! you can put the unsized type inside a [`Box`](alloc::boxed::Box).
//!
//! # Alternative approaches
//!
//! An alternative to the approach taken by Archery is to use traits with associated types to encode
//! type-level functions. This has been suggested
//! [multiple](https://github.com/orium/rpds/issues/7#issuecomment-362635901)
//! [times](https://joshlf.com/post/2018/10/18/rust-higher-kinded-types-already/#comment-4160863400),
//! but offers ugly ergonomics (see
//! [here](https://github.com/Marwes/rpds/blob/e482d5abbaa6c876d7c624e497affe7299bbeece/src/sequence/vector/mod.rs#L153)
//! and [here](https://github.com/Marwes/rpds/blob/e482d5abbaa6c876d7c624e497affe7299bbeece/src/sequence/vector/mod.rs#L249)).
extern crate alloc;
extern crate std;
pub use SharedPointer;
pub use SharedPointerKind;
pub use ArcK;
pub use RcK;