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}