1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/* 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/. */ #![cfg_attr(feature = "fatal-warnings", deny(warnings))] #![deny(clippy::correctness)] #![warn(clippy::pedantic)] #![allow(clippy::match_bool)] #![allow(clippy::if_not_else)] #![allow(clippy::stutter)] #![allow(clippy::similar_names)] #![allow(clippy::use_self)] #![allow(clippy::single_match_else)] #![allow(clippy::inline_always)] #![allow(clippy::partialeq_ne_impl)] // 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`](https://doc.rust-lang.org/std/rc/struct.Rc.html) and //! [`Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html) 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`](./shared_pointer/struct.SharedPointer.html) //! that receives the [kind of pointer](./shared_pointer/kind/trait.SharedPointerKind.html) //! 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<_, _, SharedPointerKindRc> = //! 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`](https://doc.rust-lang.org/std/boxed/struct.Box.html). //! //! # 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)). pub mod shared_pointer; pub use shared_pointer::SharedPointer; pub use shared_pointer::kind::SharedPointerKind; #[doc(no_inline)] pub use shared_pointer::kind::SharedPointerKindArc; #[doc(no_inline)] pub use shared_pointer::kind::SharedPointerKindRc;