From 2d5be08822c6b533ba40835a639ae2f0ca470ad7 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Tue, 25 Jan 2022 19:18:34 +1100 Subject: [PATCH] More documentation tweaks to clarify and explain --- README.md | 4 ++-- src/lib.rs | 29 +++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 91471de..ea53945 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ What this means is that in an ``AnyMap`` you may store zero or one values for ev This library uses a fair bit of unsafe code for several reasons: -- To support Any and CloneAny, unsafe code is required (because of how the `downcast` methods are defined in `impl dyn Any` rather than being trait methods; I think this is kind of a historical detail of the structure of `std::any::Any`); if you wanted to ditch `Clone` support this unsafety could be removed. +- To support `CloneAny`, unsafe code is required (because the downcast methods are defined on `dyn Any` rather than being trait methods); if you wanted to ditch `Clone` support this unsafety could be removed. - In the interests of performance, skipping various checks that are unnecessary because of the invariants of the data structure (no need to check the type ID when it’s been statically ensured by being used as the hash map key). @@ -22,7 +22,7 @@ This library uses a fair bit of unsafe code for several reasons: It’s not possible to remove all unsafety from this library without also removing some of the functionality. Still, at the cost of the `CloneAny` functionality and the raw interface, you can definitely remove all unsafe code. Here’s how you could do it: -- Remove the genericness of it all; +- Remove the genericness of it all (choose `dyn Any`, `dyn Any + Send` or `dyn Any + Send + Sync` and stick with it); - Merge `anymap::raw` into the normal interface, flattening it; - Change things like `.map(|any| unsafe { any.downcast_unchecked() })` to `.and_then(|any| any.downcast())` (performance cost: one extra superfluous type ID comparison, indirect). diff --git a/src/lib.rs b/src/lib.rs index a53a2d8..31b271e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,6 @@ -//! This crate provides the `AnyMap` type, a safe and convenient store for one value of each type. +//! This crate provides a safe and convenient store for one value of each type. +//! +//! Your starting point is [`Map`]. It has an example. #![warn(missing_docs, unused_results)] @@ -95,12 +97,27 @@ pub mod raw; /// The type parameter `A` allows you to use a different value type; normally you will want it to /// be `std::any::Any`, but there are other choices: /// -/// - If you want the entire map to be cloneable, use `CloneAny` instead of `Any`. -/// - You can add on `+ Send` or `+ Send + Sync` (e.g. `Map`) to add those bounds. +/// - If you want the entire map to be cloneable, use `CloneAny` instead of `Any`; with that, you +/// can only add types that implement `Clone` to the map. +/// - You can add on `+ Send` or `+ Send + Sync` (e.g. `Map`) to add those auto +/// traits. +/// +/// Cumulatively, there are thus six forms of map: +/// +/// - [Map]<dyn [std::any::Any]>, also spelled [`AnyMap`] for convenience. +/// - [Map]<dyn [std::any::Any] + Send> +/// - [Map]<dyn [std::any::Any] + Send + Sync> +/// - [Map]<dyn [CloneAny]> +/// - [Map]<dyn [CloneAny] + Send> +/// - [Map]<dyn [CloneAny] + Send + Sync> +/// +/// ## Example +/// +/// (Here using the [`AnyMap`] convenience alias; the first line could use +/// [anymap::Map][Map]::<[std::any::Any]>::new() instead if desired.) /// /// ```rust -/// # use anymap::AnyMap; -/// let mut data = AnyMap::new(); +/// let mut data = anymap::AnyMap::new(); /// assert_eq!(data.get(), None::<&i32>); /// data.insert(42i32); /// assert_eq!(data.get(), Some(&42i32)); @@ -135,7 +152,7 @@ impl Clone for Map where Box: Clone { } } -/// The most common type of `Map`: just using `Any`. +/// The most common type of `Map`: just using `Any`; [Map]<dyn [Any]>. /// /// Why is this a separate type alias rather than a default value for `Map`? `Map::new()` /// doesn’t seem to be happy to infer that it should go with the default value. -- 2.42.0