rshyper_hmap/
lib.rs

1/*
2    appellation: rshyper-hmap <library>
3    authors: @FL03
4*/
5//! A map-based implementation of a hypergraph providing efficient storage and manipulation of
6//! hypernodes and hyperedges.
7//!
8//! ## Overview
9//!
10//! This implementation focuses on providing a flexible and efficient representation of a
11//! hypergraph. The [`HyperMap`] is parameterized by the following types:
12//!
13//! - `N`: the type of weight associated with a hypernode
14//! - `E`: the type of weight associated with a hyperedge
15//! - `A`: the attributes of the graph are implementors of the [`GraphProps`] trait
16//!   - `A::Kind`: the _kind_ of hypergraph, either [`Directed`](rshyper::Directed) or [`Undirected`](rshyper::Undirected)
17//!   - `A::Ix`: the type of indices used by the instance; bounded by the [`RawIndex` trait
18//! - `S`: the type of [`BuildHasher`] used for the underling stores
19//!
20//! This is done to maximize compatibility and flexibility, allowing users to define their own
21//! hypergraphs with custom node and edge types, as well as different index types and hashers.
22//!
23//! ### Backend
24//!
25//! The underlying storage mechanics are based on the [`hashbrown`](https://crates.io/crates/hashbrown)
26//! crate, which is a Rust implementation of [Google's SwissTable](https://abseil.io/blog/20180927-swisstables)
27//! algorithm. This is largely done to benfit from the additional feature set natively
28//! available within the crate versus the standard [`HashMap`](std::collections::HashMap)
29//! implementation. That being said, it is important to note that for any applications where
30//! security it a concerin it is highly recommended to use the [`RandomState`](std::hash::RandomState)
31//! as the default hasher in lieu of the [`DefaultHashBuilder`] from [`foldhash`](https://crates.io/crates/foldhash)
32//! as it fails to prevent against attacks such as `Hash-DoS`. See the [`hashbrown`](https://crates.io/crates/hashbrown)
33//! for more information on the security implications of using a custom hasher.
34//!
35//! ## Features
36//!
37//! The [`HyperMap`] supports various features to enhance its functionality:
38//!
39//! - `algo`: enables the algorithmic operators from the [`rshyper_algo`](https://crates.io/crates/rshyper_algo) crate
40//! - `rayon`: enables parallel processing capabilities using the `rayon` crate
41//! - `serde`: enables serialization and deserialization of hypergraphs using the `serde` crate
42//!
43//! ## Examples
44//!
45//! For more detailed examples, please refer to the [examples directory](https://github.com/FL03/rshyper/blob/main/rshyper/examples).
46//!
47//! ### _Example #1: Basic Usage_
48//!
49//! ```rust
50//! use rshyper_core::Weight;
51//! use rshyper_hmap::HyperMap;
52//! // initialize a ne, undirected hypergraph
53//! let mut graph = HyperMap::<i32, i32>::undirected();
54//! // insert some nodes with and without weights
55//! let v0 = graph.add_vertex().expect("failed to add vertex");
56//! let v1 = graph.add_node(Weight(42)).expect("failed to add the node");
57//! let v2 = graph.add_node(Weight(100)).expect("failed to add the node");
58//! // insert an edge between the two nodes
59//! let e0 = graph.add_edge([v0, v1, v2], Weight(100)).expect("failed to add edge");
60//! // verify the size of the graph; (number of edges)
61//! assert_eq!(graph.size(), 1);
62//! // verify the order of the graph; (number of nodes)
63//! assert_eq!(graph.order(), 3);
64//! ```
65//!
66#![crate_type = "lib"]
67#![doc(
68    html_logo_url = "https://raw.githubusercontent.com/FL03/rshyper/main/.artifacts/assets/logo.svg",
69    html_favicon_url = "https://raw.githubusercontent.com/FL03/rshyper/main/.artifacts/assets/logo.svg"
70)]
71#![allow(
72    clippy::missing_safety_doc,
73    clippy::module_inception,
74    clippy::needless_doctest_main,
75    clippy::should_implement_trait
76)]
77#![cfg_attr(not(feature = "std"), no_std)]
78#![cfg_attr(feature = "nightly", feature(allocator_api))]
79// **** WARNING ****
80// the `std` feature is required by the crate, only declared for concistency w.r.t. the
81// available features and for ensuring that all the depencies actually implement the `std`
82// feature since the workspace naturally imports them with the `default-features = false`
83// flag toggled
84// **** WARNING ****
85#![cfg(feature = "std")]
86/// declare the macros module for use throughout the crate
87#[macro_use]
88pub(crate) mod macros {
89    #[macro_use]
90    pub mod seal;
91}
92
93#[cfg(feature = "alloc")]
94extern crate alloc;
95
96extern crate rshyper_core as rshyper;
97
98#[doc(inline)]
99pub use self::{graph::*, types::prelude::*};
100
101mod graph;
102
103mod impls {
104    pub mod impl_graph;
105    pub mod impl_hyper_graph;
106    pub mod impl_iter;
107    pub mod impl_ops;
108    pub mod impl_repr;
109
110    #[cfg(feature = "algo")]
111    pub mod impl_algo;
112    #[cfg(feature = "serde")]
113    pub mod impl_serde;
114
115    #[doc(hidden)]
116    #[allow(deprecated)]
117    pub mod impl_deprecated;
118}
119
120pub mod iter {
121    //! this module defines various iterators for the [`HyperMap`](super::HyperMap)
122    #[doc(inline)]
123    pub use self::prelude::*;
124
125    pub mod edges;
126    pub mod nodes;
127
128    pub(crate) mod prelude {
129        #[doc(inline)]
130        pub use super::edges::*;
131        #[doc(inline)]
132        pub use super::nodes::*;
133    }
134}
135
136mod types {
137    //! this module defines various types and type aliases in support of the [`HyperMap`](super::HyperMap)
138    //! implementation
139    #[doc(inline)]
140    pub use self::prelude::*;
141
142    mod aliases;
143
144    pub(crate) mod prelude {
145        #[doc(inline)]
146        pub use super::aliases::*;
147    }
148}
149
150#[doc(hidden)]
151#[allow(missing_docs)]
152pub mod prelude {
153    pub use super::graph::*;
154    pub use super::iter::prelude::*;
155    pub use super::types::prelude::*;
156}