X-Git-Url: https://git.chrismorgan.info/anymap/blobdiff_plain/b3811cf0d1bdab6154534eda1903c930885749ec..0a1c85f8655a71b995d228ed0c9496f732268c5b:/src/lib.rs?ds=sidebyside diff --git a/src/lib.rs b/src/lib.rs index bcd5c23..6366c70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,26 @@ -//! 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)] -use std::any::TypeId; -use std::marker::PhantomData; +#![cfg_attr(not(feature = "std"), no_std)] + +use core::any::{Any, TypeId}; +use core::marker::PhantomData; + +#[cfg(not(any(feature = "std", feature = "hashbrown")))] +compile_error!("anymap: you must enable the 'std' feature or the 'hashbrown' feature"); + +#[cfg(not(feature = "std"))] +extern crate alloc; + +#[cfg(not(feature = "std"))] +use alloc::boxed::Box; use raw::RawMap; -use any::{UncheckedAnyExt, IntoBox, Any}; +use any::{UncheckedAnyExt, IntoBox}; +pub use any::CloneAny; macro_rules! impl_common_methods { ( @@ -75,24 +89,46 @@ macro_rules! impl_common_methods { self.$field.clear() } } + + impl Default for $t { + #[inline] + fn default() -> $t { + $t::new() + } + } } } -pub mod any; +mod any; pub mod raw; /// A collection containing zero or one values for any given type and allowing convenient, /// type-safe access to those values. /// /// The type parameter `A` allows you to use a different value type; normally you will want it to -/// be `anymap::any::Any`, but there are other choices: +/// be `core::any::Any` (also known as `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` and/or `+ 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 [core::any::Any]>, also spelled [`AnyMap`] for convenience. +/// - [Map]<dyn [core::any::Any] + Send> +/// - [Map]<dyn [core::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]::<[core::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)); @@ -113,7 +149,7 @@ pub mod raw; /// /// Values containing non-static references are not permitted. #[derive(Debug)] -pub struct Map { +pub struct Map { raw: RawMap, } @@ -127,12 +163,12 @@ 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. /// It’s a bit sad, really. Ah well, I guess this approach will do. -pub type AnyMap = Map; +pub type AnyMap = Map; impl_common_methods! { field: Map.raw; @@ -211,10 +247,10 @@ impl AsMut> for Map { } } -impl Into> for Map { +impl From> for RawMap { #[inline] - fn into(self) -> RawMap { - self.raw + fn from(map: Map) -> RawMap { + map.raw } } @@ -304,8 +340,7 @@ impl<'a, A: ?Sized + UncheckedAnyExt, V: IntoBox> VacantEntry<'a, A, V> { #[cfg(test)] mod tests { - use {Map, AnyMap, Entry}; - use any::{Any, CloneAny}; + use super::*; #[derive(Clone, Debug, PartialEq)] struct A(i32); #[derive(Clone, Debug, PartialEq)] struct B(i32); @@ -387,11 +422,17 @@ mod tests { } test_entry!(test_entry_any, AnyMap); - test_entry!(test_entry_cloneany, Map); + test_entry!(test_entry_cloneany, Map); + + #[test] + fn test_default() { + let map: AnyMap = Default::default(); + assert_eq!(map.len(), 0); + } #[test] fn test_clone() { - let mut map: Map = Map::new(); + let mut map: Map = Map::new(); let _ = map.insert(A(1)); let _ = map.insert(B(2)); let _ = map.insert(D(3)); @@ -414,26 +455,21 @@ mod tests { fn assert_send() { } fn assert_sync() { } fn assert_clone() { } - fn assert_debug() { } - assert_send::>(); - assert_send::>(); - assert_sync::>(); - assert_sync::>(); - assert_debug::>(); - assert_debug::>(); - assert_debug::>(); - assert_debug::>(); - assert_send::>(); - assert_send::>(); - assert_sync::>(); - assert_sync::>(); - assert_clone::>(); - assert_clone::>(); - assert_clone::>(); - assert_clone::>(); - assert_debug::>(); - assert_debug::>(); - assert_debug::>(); - assert_debug::>(); + fn assert_debug() { } + assert_send::>(); + assert_send::>(); + assert_sync::>(); + assert_debug::>(); + assert_debug::>(); + assert_debug::>(); + assert_send::>(); + assert_send::>(); + assert_sync::>(); + assert_clone::>(); + assert_clone::>(); + assert_clone::>(); + assert_debug::>(); + assert_debug::>(); + assert_debug::>(); } }