Skip to content

Commit

Permalink
Improve documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Apr 26, 2023
1 parent ac03973 commit 1fb0880
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 155 deletions.
106 changes: 0 additions & 106 deletions fixed-map-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,111 +68,6 @@ mod context;
mod symbol;
mod unit_variants;

/// Derive to implement the `Key` trait.
///
/// This derive implements the `Key` trait for a given type.
///
/// The `Key` trait is what allows `fixed_map` to set up storage for a type that
/// will be the key in a fixed map.
///
/// # Container attributes
///
/// #### `#[key(bitset)]`
///
/// This ensures that backing storage is performed with a bitset when used with
/// a [`Set`].
///
/// ```rust
/// use fixed_map::{Key, Set};
///
/// #[derive(Clone, Copy, Key)]
/// pub enum Regular {
/// First,
/// Second,
/// Third,
/// }
///
///
/// #[derive(Clone, Copy, Key)]
/// #[key(bitset)]
/// pub enum Bits {
/// First,
/// Second,
/// Third,
/// }
///
/// // Normal storage uses an array of booleans:
/// assert_eq!(std::mem::size_of::<Set<Regular>>(), 3);
///
/// // Bitset storage uses a single u8 (or other appropriate type based on size):
/// assert_eq!(std::mem::size_of::<Set<Bits>>(), 1);
/// ```
///
/// # Guide
///
/// Given the following enum:
///
/// ```rust
/// use fixed_map::Key;
///
/// #[derive(Clone, Copy, Key)]
/// pub enum MyKey {
/// First,
/// Second,
/// Third,
/// }
/// ```
///
/// It performs the following simplified expansion:
///
/// ```rust,no_compile,no_run
/// use fixed_map::Key;
///
/// #[derive(Clone, Copy)]
/// pub enum MyKey {
/// First,
/// Second,
/// Third,
/// }
///
/// /// Build a storage struct containing an item for each key:
/// pub struct MyKeyStorage<V> {
/// /// Storage for `MyKey::First`.
/// f1: Option<V>,
/// /// Storage for `MyKey::Second`.
/// f2: Option<V>,
/// /// Storage for `MyKey::Third`.
/// f3: Option<V>,
/// }
///
/// /// Implement storage for `KeyStorage`.
/// impl<V> fixed_map::storage::Storage<MyKey, V> for KeyStorage<V> {
/// fn get(&self, key: MyKey) -> Option<&V> {
/// match key {
/// MyKey::First => self.f1.as_ref(),
/// MyKey::Second => self.f2.as_ref(),
/// MyKey::Third => self.f3.as_ref(),
/// }
/// }
///
/// /* skipped */
/// }
///
/// impl<V> Default for KeyStorage<V> {
/// fn default() -> Self {
/// Self {
/// f1: None,
/// f2: None,
/// f3: None,
/// }
/// }
/// }
///
/// /// Implement the `Key` trait to point out storage.
/// impl<V> fixed_map::Key<Key, V> for MyKey {
/// type Storage = KeyStorage<V>;
/// }
/// ```
#[proc_macro_derive(Key, attributes(key))]
pub fn storage_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let ast = syn::parse_macro_input!(input as DeriveInput);
Expand All @@ -193,7 +88,6 @@ pub fn storage_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream
quote!(#(#compile_errors)*).into()
}

/// Derive to implement the `Key` trait.
fn impl_storage(cx: &context::Ctxt<'_>) -> Result<TokenStream, ()> {
let opts = attrs::parse(cx)?;

Expand Down
8 changes: 4 additions & 4 deletions src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ use crate::set::storage::{BooleanSetStorage, OptionSetStorage, SetStorage, Singl
/// [`Map`]: crate::Map
/// [`Set`]: crate::Set
pub trait Key: Copy {
/// The [`Map`] storage implementation to use for the key implementing
/// this trait.
/// The [`Map`][crate::Map] storage implementation to use for the key
/// implementing this trait.
type MapStorage<V>: MapStorage<Self, V>;

/// The [`Set`] storage implementation to use for the key implementing
/// this trait.
/// The [`Set`][crate::Set] storage implementation to use for the key
/// implementing this trait.
type SetStorage: SetStorage<Self>;
}

Expand Down
214 changes: 170 additions & 44 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,54 +284,180 @@
#![no_std]
#![deny(unsafe_code)]
#![deny(missing_docs)]
// Enable pedantic lints as warnings so we don't break builds when
// lints are modified or new lints are added to clippy.
#![warn(
// Enable more useful rustc lints
absolute_paths_not_starting_with_crate,
elided_lifetimes_in_paths,
explicit_outlives_requirements,
keyword_idents,
macro_use_extern_crate,
meta_variable_misuse,
missing_copy_implementations,
non_ascii_idents,
noop_method_call,
pointer_structural_match,
single_use_lifetimes,
trivial_casts,
trivial_numeric_casts,
unreachable_pub,
unused_extern_crates,
unused_import_braces,
unused_lifetimes,
unused_macro_rules,
unused_qualifications,
unused_tuple_struct_fields,
variant_size_differences,
// Enable pedantic clippy lints
clippy::pedantic,
// Useful clippy lints for no_std support
clippy::std_instead_of_core,
clippy::std_instead_of_alloc,
clippy::alloc_instead_of_core,
// Useful extra perf lints
clippy::missing_inline_in_public_items
)]
// `clippy::pedantic` exceptions
#![allow(
// style choice
clippy::module_name_repetitions,
// false positive
clippy::type_repetition_in_bounds,
// false positive
clippy::expl_impl_clone_on_copy
)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(keyword_idents)]
#![warn(macro_use_extern_crate)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(non_ascii_idents)]
#![warn(noop_method_call)]
#![warn(pointer_structural_match)]
#![warn(single_use_lifetimes)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unreachable_pub)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_macro_rules)]
#![warn(unused_qualifications)]
#![warn(unused_tuple_struct_fields)]
#![warn(variant_size_differences)]
#![warn(clippy::pedantic)]
#![warn(clippy::std_instead_of_core)]
#![warn(clippy::std_instead_of_alloc)]
#![warn(clippy::alloc_instead_of_core)]
#![warn(clippy::missing_inline_in_public_items)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::type_repetition_in_bounds)]
#![allow(clippy::expl_impl_clone_on_copy)]

mod key;
pub use self::key::Key;

/// Derive to implement the [`Key`] trait.
///
/// This derive implements the [`Key`] trait for a given type.
///
/// The [`Key`] trait is what allows `fixed_map` to set up storage for a type
/// that will be the key in a fixed map.
///
/// > Note: this requires the `::fixed_map` crate to be in scope when it's
/// > derived.
///
/// # Container attributes
///
/// #### `#[key(bitset)]`
///
/// This ensures that backing storage is performed with a bitset when used with
/// a [`Set`].
///
/// ```rust
/// use fixed_map::{Key, Set};
///
/// #[derive(Clone, Copy, Key)]
/// pub enum Regular {
/// First,
/// Second,
/// Third,
/// }
///
/// #[derive(Clone, Copy, Key)]
/// #[key(bitset)]
/// pub enum Bits {
/// First,
/// Second,
/// Third,
/// }
///
/// // Normal storage uses an array of booleans:
/// assert_eq!(std::mem::size_of::<Set<Regular>>(), 3);
///
/// // Bitset storage uses a single u8 (or other appropriate type based on size):
/// assert_eq!(std::mem::size_of::<Set<Bits>>(), 1);
/// ```
///
/// > **Warning:** not all operations will be implemented when this attributes
/// > is present, so some container methods might not work.
///
/// # Guide
///
/// Given the following enum:
///
/// ```rust
/// use fixed_map::Key;
///
/// #[derive(Clone, Copy, Key)]
/// pub enum MyKey {
/// First,
/// Second,
/// Third,
/// }
/// ```
///
/// It performs the following expansion:
///
/// ```rust,no_compile,no_run
/// use fixed_map::Key;
///
/// #[derive(Clone, Copy)]
/// pub enum MyKey {
/// First,
/// Second,
/// Third,
/// }
///
/// /// Build a storage struct containing an item for each key:
/// pub struct MyKeyMapStorage<V> {
/// /// Storage for `MyKey::First`.
/// f1: Option<V>,
/// /// Storage for `MyKey::Second`.
/// f2: Option<V>,
/// /// Storage for `MyKey::Third`.
/// f3: Option<V>,
/// }
///
/// /// Build a storage struct containing an element for each key:
/// pub struct MyKeySetStorage {
/// data: [bool; 3],
/// }
///
/// /// Implement map storage for key.
/// impl<V> fixed_map::map::storage::MapStorage<MyKey, V> for MyKeyMapStorage<V> {
/// fn get(&self, key: MyKey) -> Option<&V> {
/// match key {
/// MyKey::First => self.f1.as_ref(),
/// MyKey::Second => self.f2.as_ref(),
/// MyKey::Third => self.f3.as_ref(),
/// }
/// }
///
/// /* skipped */
/// }
///
/// /// Implement set storage for key.
/// impl fixed_map::set::storage::SetStorage<MyKey> for MyKeySetStorage {
/// fn contains(&self, key: MyKey) -> Option<&V> {
/// let [a, b, c] = &self.data;
///
/// match key {
/// MyKey::First => a,
/// MyKey::Second => b,
/// MyKey::Third => c,
/// }
/// }
///
/// /* skipped */
/// }
///
/// impl Default for MyKeyMapStorage<V> {
/// fn default() -> Self {
/// Self {
/// f1: None,
/// f2: None,
/// f3: None,
/// }
/// }
/// }
///
/// impl Default for MyKeySetStorage {
/// fn default() -> Self {
/// Self {
/// data: [false, false, false]
/// }
/// }
/// }
///
/// /// Implement the Key trait to point out storage.
/// impl fixed_map::Key for MyKey {
/// type MapStorage<V> = MyKeyMapStorage<V>;
/// type SetStorage = MyKeySetStorage;
/// }
/// ```
#[doc(inline)]
pub use fixed_map_derive::*;
pub use fixed_map_derive::Key;

pub mod map;
#[doc(inline)]
Expand Down
2 changes: 1 addition & 1 deletion src/map/storage.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Module that defines the [`Storage`] trait.
//! Module that defines the [`MapStorage`] trait.

mod boolean;
pub(crate) use self::boolean::BooleanMapStorage;
Expand Down

0 comments on commit 1fb0880

Please sign in to comment.