igraph/constants.rs
1//! Rust enumerations for igraph's C constants (`igraph_constants.h`).
2//!
3//! Each enum converts into the raw C value with [`From`] (e.g.
4//! `igraph_neimode_t::from(NeighborMode::Out)`), and back with [`TryFrom`]
5//! (an [`ErrorKind::InvalidValue`](crate::error::ErrorKind::InvalidValue)
6//! error for values that are not part of the enumeration). All of them are
7//! re-exported by the [prelude](crate::prelude). Module-specific enums (e.g.
8//! layout or community options) live next to the functions that use them.
9//!
10//! ```
11//! use igraph::{ffi, prelude::*};
12//!
13//! // Out-neighbors follow the edge direction, in-neighbors go against it.
14//! let g = Graph::from_edges(&[(0, 1), (2, 1), (1, 1)], 3, true).unwrap();
15//! assert_eq!(g.neighbors(1, NeighborMode::Out).unwrap(), vec![1]);
16//! assert_eq!(g.neighbors(1, NeighborMode::In).unwrap(), vec![0, 1, 2]);
17//! assert_eq!(g.degree(1, NeighborMode::All, Loops::Twice).unwrap(), vec![4]);
18//! assert_eq!(g.degree(1, NeighborMode::All, Loops::None).unwrap(), vec![2]);
19//!
20//! // Conversions to and from the raw C constants.
21//! assert_eq!(ffi::igraph_neimode_t::from(NeighborMode::In), ffi::igraph_neimode_t_IGRAPH_IN);
22//! assert_eq!(NeighborMode::try_from(ffi::igraph_neimode_t_IGRAPH_ALL).unwrap(), NeighborMode::All);
23//! assert!(Order::try_from(42 as ffi::igraph_order_t).is_err());
24//! ```
25//!
26//! | Enum | C type | Used by (for example) |
27//! |------|--------|-----------------------|
28//! | [`NeighborMode`] | `igraph_neimode_t` | [`Graph::neighbors`](crate::Graph::neighbors), [`Graph::degree`](crate::Graph::degree), [`Graph::bfs`](crate::Graph::bfs), [`Graph::distances`](crate::Graph::distances) |
29//! | [`Loops`] | `igraph_loops_t` | [`Graph::degree`](crate::Graph::degree), [`Graph::neighbors_with`](crate::Graph::neighbors_with), [`Graph::get_adjacency`](crate::Graph::get_adjacency) |
30//! | [`EdgeTypeSw`], [`AllowedEdgeTypes`] | `igraph_edge_type_sw_t` | [`Graph::rewire`](crate::Graph::rewire), [`Graph::erdos_renyi_game_gnm`](crate::Graph::erdos_renyi_game_gnm) |
31//! | [`Order`] | `igraph_order_t` | [`VectorInt::sort_ind`](crate::vector::VectorInt::sort_ind), [`Graph::sort_vertex_ids_by_degree`](crate::Graph::sort_vertex_ids_by_degree) |
32//! | [`Connectedness`] | `igraph_connectedness_t` | [`Graph::connected_components`](crate::Graph::connected_components), [`Graph::is_connected`](crate::Graph::is_connected) |
33//! | [`Reciprocity`] | `igraph_reciprocity_t` | [`Graph::reciprocity`](crate::Graph::reciprocity) |
34//! | [`Adjacency`], [`GetAdjacency`] | `igraph_adjacency_t`, `igraph_get_adjacency_t` | [`Graph::adjacency`](crate::Graph::adjacency), [`Graph::get_adjacency`](crate::Graph::get_adjacency) |
35//! | [`StarMode`], [`WheelMode`], [`TreeMode`] | `igraph_star_mode_t`, `igraph_wheel_mode_t`, `igraph_tree_mode_t` | [`Graph::star`](crate::Graph::star), [`Graph::wheel`](crate::Graph::wheel), [`Graph::kary_tree`](crate::Graph::kary_tree) |
36//! | [`DegreeSequenceMethod`], [`RealizeDegseq`] | `igraph_degseq_t`, `igraph_realize_degseq_t` | [`Graph::degree_sequence_game`](crate::Graph::degree_sequence_game), [`Graph::realize_degree_sequence`](crate::Graph::realize_degree_sequence) |
37//! | [`RandomTreeMethod`], [`BarabasiAlgorithm`], [`ChungLuVariant`] | `igraph_random_tree_t`, `igraph_barabasi_algorithm_t`, `igraph_chung_lu_t` | [`Graph::tree_game`](crate::Graph::tree_game), [`Graph::barabasi_game`](crate::Graph::barabasi_game), [`Graph::chung_lu_game`](crate::Graph::chung_lu_game) |
38//! | [`EdgeOrder`] | `igraph_edgeorder_type_t` | [`EdgeSelector::AllOrdered`](crate::selector::EdgeSelector::AllOrdered) |
39//! | [`ToDirected`], [`ToUndirected`] | `igraph_to_directed_t`, `igraph_to_undirected_t` | [`Graph::to_directed`](crate::Graph::to_directed), [`Graph::to_undirected`](crate::Graph::to_undirected) |
40//! | [`VconnNei`] | `igraph_vconn_nei_t` | [`Graph::st_vertex_connectivity`](crate::Graph::st_vertex_connectivity) |
41//! | [`SpincommUpdate`], [`SpinglassImplementation`], [`LpaVariant`], [`CommunityComparison`] | `igraph_spincomm_update_t`, ... | [`Graph::community_spinglass`](crate::Graph::community_spinglass), [`Graph::community_label_propagation`](crate::Graph::community_label_propagation), [`compare_communities`](crate::community::compare_communities) |
42//! | [`TransitivityMode`] | `igraph_transitivity_mode_t` | [`Graph::transitivity_local_undirected`](crate::Graph::transitivity_local_undirected) |
43//! | [`AddWeights`] | `igraph_add_weights_t` | [`NcolLglOptions`](crate::foreign::NcolLglOptions) |
44//! | [`FasAlgorithm`], [`FvsAlgorithm`] | `igraph_fas_algorithm_t`, `igraph_fvs_algorithm_t` | [`Graph::feedback_arc_set`](crate::Graph::feedback_arc_set), [`Graph::feedback_vertex_set`](crate::Graph::feedback_vertex_set) |
45//! | [`SubgraphImplementation`] | `igraph_subgraph_implementation_t` | [`Graph::induced_subgraph`](crate::Graph::induced_subgraph) |
46//! | [`LayoutGrid`] | `igraph_layout_grid_t` | [`FruchtermanReingoldOptions`](crate::layout::FruchtermanReingoldOptions) |
47//! | [`RandomWalkStuck`], [`VoronoiTiebreaker`] | `igraph_random_walk_stuck_t`, `igraph_voronoi_tiebreaker_t` | [`Graph::random_walk`](crate::Graph::random_walk), [`Graph::voronoi`](crate::Graph::voronoi) |
48//! | [`MstAlgorithm`], [`Product`] | `igraph_mst_algorithm_t`, `igraph_product_t` | [`Graph::minimum_spanning_tree`](crate::Graph::minimum_spanning_tree), [`Graph::product`](crate::Graph::product) |
49//! | [`MatrixStorage`] | `igraph_matrix_storage_t` | raw FFI functions taking flat matrices |
50
51use crate::ffi::*;
52
53/// Declares a Rust enum mirroring a C enum, together with `From`/`TryFrom`
54/// conversions to and from the raw type.
55///
56/// ```ignore
57/// ffi_enum! {
58/// /// Docs.
59/// pub enum NeighborMode: igraph_neimode_t {
60/// /// Out-neighbors.
61/// Out = igraph_neimode_t_IGRAPH_OUT,
62/// }
63/// }
64/// ```
65#[macro_export]
66macro_rules! ffi_enum {
67 (
68 $(#[$meta:meta])*
69 $vis:vis enum $name:ident : $raw:ty {
70 $( $(#[$vmeta:meta])* $variant:ident = $value:path ),+ $(,)?
71 }
72 ) => {
73 $(#[$meta])*
74 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
75 $vis enum $name {
76 $( $(#[$vmeta])* $variant ),+
77 }
78
79 impl From<$name> for $raw {
80 fn from(value: $name) -> $raw {
81 match value {
82 $( $name::$variant => $value as $raw ),+
83 }
84 }
85 }
86
87 impl TryFrom<$raw> for $name {
88 type Error = $crate::error::Error;
89 #[allow(non_upper_case_globals, unreachable_patterns)]
90 fn try_from(value: $raw) -> $crate::error::Result<Self> {
91 $( if value == $value as $raw { return Ok($name::$variant); } )+
92 Err($crate::error::Error::invalid(format!(
93 "invalid value {} for {}", value, stringify!($name)
94 )))
95 }
96 }
97 };
98}
99
100ffi_enum! {
101 /// Which neighbors (or incident edges) to consider in directed graphs
102 /// (`igraph_neimode_t`). Ignored for undirected graphs.
103 pub enum NeighborMode: igraph_neimode_t {
104 /// Follow edges along their direction (successors).
105 Out = igraph_neimode_t_IGRAPH_OUT,
106 /// Follow edges against their direction (predecessors).
107 In = igraph_neimode_t_IGRAPH_IN,
108 /// Ignore edge directions.
109 All = igraph_neimode_t_IGRAPH_ALL,
110 }
111}
112
113impl NeighborMode {
114 /// The mode with the direction reversed (`All` stays `All`).
115 pub fn reverse(self) -> Self {
116 match self {
117 Self::Out => Self::In,
118 Self::In => Self::Out,
119 Self::All => Self::All,
120 }
121 }
122}
123
124ffi_enum! {
125 /// How self-loops are counted (`igraph_loops_t`).
126 pub enum Loops: igraph_loops_t {
127 /// Ignore loop edges.
128 None = igraph_loops_t_IGRAPH_NO_LOOPS,
129 /// Count each loop twice, as it has two endpoints at the same vertex
130 /// (the graph theoretical convention, which keeps the handshake
131 /// lemma true).
132 Twice = igraph_loops_t_IGRAPH_LOOPS_TWICE,
133 /// Count each loop once. Only meaningful when edge directions are
134 /// ignored: for out- or in-degrees of directed graphs each loop
135 /// counts once anyway.
136 Once = igraph_loops_t_IGRAPH_LOOPS_ONCE,
137 }
138}
139
140impl From<bool> for Loops {
141 /// `true` maps to [`Loops::Twice`] (igraph's `IGRAPH_LOOPS`), `false` to [`Loops::None`].
142 fn from(loops: bool) -> Self {
143 if loops { Loops::Twice } else { Loops::None }
144 }
145}
146
147ffi_enum! {
148 /// Which kind of edges a random generator may produce (`igraph_edge_type_sw_t`).
149 pub enum EdgeTypeSw: igraph_edge_type_sw_t {
150 /// Only simple graphs: no loops, no multi-edges.
151 Simple = IGRAPH_SIMPLE_SW,
152 /// Self-loops allowed.
153 Loops = IGRAPH_LOOPS_SW,
154 /// Multi-edges allowed.
155 Multi = IGRAPH_MULTI_SW,
156 }
157}
158
159/// Which kinds of edges a graph may contain, as a set of flags
160/// (`igraph_edge_type_sw_t`, including the combination
161/// `IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW`).
162///
163/// This is the single crate-wide type for igraph's edge-type switches: it is
164/// taken by the random generators of [`games`](crate::games) (e.g.
165/// [`Graph::erdos_renyi_game_gnm`](crate::Graph::erdos_renyi_game_gnm)), by the
166/// graphicality tests of [`mixing`](crate::mixing) (e.g.
167/// [`is_graphical`](crate::mixing::is_graphical)) and by the deterministic
168/// realizations of [`constructors`](crate::constructors) (e.g.
169/// [`Graph::realize_degree_sequence`](crate::Graph::realize_degree_sequence)).
170/// It is re-exported as `games::AllowedEdgeTypes`,
171/// `mixing::AllowedEdgeTypes` and `constructors::AllowedEdgeTypes`, and all
172/// these paths name the very same type.
173///
174/// Unlike [`EdgeTypeSw`], which lists the three basic flags, this type can
175/// express their combination: build it with the associated constants
176/// ([`SIMPLE`](Self::SIMPLE), [`LOOPS`](Self::LOOPS), [`MULTI`](Self::MULTI),
177/// [`ALL`](Self::ALL)), with a struct literal, or by or-ing flags together.
178/// Every function taking it accepts `impl Into<AllowedEdgeTypes>`, so an
179/// [`EdgeTypeSw`] can be passed directly.
180///
181/// ```
182/// use igraph::{ffi, prelude::*};
183///
184/// let both = AllowedEdgeTypes::LOOPS | AllowedEdgeTypes::MULTI;
185/// assert_eq!(both, AllowedEdgeTypes::ALL);
186/// assert_eq!(AllowedEdgeTypes::from(EdgeTypeSw::Multi), AllowedEdgeTypes::MULTI);
187/// assert_eq!(EdgeTypeSw::Loops | EdgeTypeSw::Multi, AllowedEdgeTypes::ALL);
188///
189/// // Raw C flags, both ways.
190/// let raw = ffi::igraph_edge_type_sw_t::from(AllowedEdgeTypes::ALL);
191/// assert_eq!(raw, ffi::IGRAPH_LOOPS_SW | ffi::IGRAPH_MULTI_SW);
192/// assert_eq!(AllowedEdgeTypes::try_from(raw).unwrap(), AllowedEdgeTypes::ALL);
193///
194/// // One name, one type, whatever the module path.
195/// let t: igraph::games::AllowedEdgeTypes = igraph::constructors::AllowedEdgeTypes::MULTI;
196/// assert_eq!(t, igraph::mixing::AllowedEdgeTypes::MULTI);
197/// ```
198#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
199pub struct AllowedEdgeTypes {
200 /// Whether self-loops are allowed.
201 pub loops: bool,
202 /// Whether multi-edges (parallel edges) are allowed.
203 pub multi: bool,
204}
205
206impl AllowedEdgeTypes {
207 /// Simple graphs only: neither self-loops nor multi-edges (`IGRAPH_SIMPLE_SW`).
208 pub const SIMPLE: Self = Self {
209 loops: false,
210 multi: false,
211 };
212 /// Self-loops allowed, but no multi-edges (`IGRAPH_LOOPS_SW`); at most
213 /// one self-loop per vertex.
214 pub const LOOPS: Self = Self {
215 loops: true,
216 multi: false,
217 };
218 /// Multi-edges allowed, but no self-loops (`IGRAPH_MULTI_SW`).
219 pub const MULTI: Self = Self {
220 loops: false,
221 multi: true,
222 };
223 /// Both self-loops and multi-edges allowed (`IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW`).
224 pub const ALL: Self = Self {
225 loops: true,
226 multi: true,
227 };
228
229 /// Former enum variant name of [`SIMPLE`](Self::SIMPLE), kept so that
230 /// code written for the old `constructors::AllowedEdgeTypes` enum compiles.
231 #[doc(hidden)]
232 #[allow(non_upper_case_globals)]
233 pub const Simple: Self = Self::SIMPLE;
234 /// Former enum variant name of [`LOOPS`](Self::LOOPS).
235 #[doc(hidden)]
236 #[allow(non_upper_case_globals)]
237 pub const Loops: Self = Self::LOOPS;
238 /// Former enum variant name of [`MULTI`](Self::MULTI).
239 #[doc(hidden)]
240 #[allow(non_upper_case_globals)]
241 pub const Multi: Self = Self::MULTI;
242 /// Former enum variant name of [`ALL`](Self::ALL).
243 #[doc(hidden)]
244 #[allow(non_upper_case_globals)]
245 pub const LoopsAndMulti: Self = Self::ALL;
246
247 /// The raw igraph bit flags.
248 pub const fn to_raw(self) -> igraph_edge_type_sw_t {
249 let mut raw = IGRAPH_SIMPLE_SW as igraph_edge_type_sw_t;
250 if self.loops {
251 raw |= IGRAPH_LOOPS_SW as igraph_edge_type_sw_t;
252 }
253 if self.multi {
254 raw |= IGRAPH_MULTI_SW as igraph_edge_type_sw_t;
255 }
256 raw
257 }
258}
259
260impl From<EdgeTypeSw> for AllowedEdgeTypes {
261 fn from(sw: EdgeTypeSw) -> Self {
262 match sw {
263 EdgeTypeSw::Simple => Self::SIMPLE,
264 EdgeTypeSw::Loops => Self::LOOPS,
265 EdgeTypeSw::Multi => Self::MULTI,
266 }
267 }
268}
269
270impl From<AllowedEdgeTypes> for igraph_edge_type_sw_t {
271 fn from(types: AllowedEdgeTypes) -> Self {
272 types.to_raw()
273 }
274}
275
276impl TryFrom<igraph_edge_type_sw_t> for AllowedEdgeTypes {
277 type Error = crate::error::Error;
278 /// Accepts exactly the four valid flag combinations; any other bit
279 /// pattern is an [`ErrorKind::InvalidValue`](crate::error::ErrorKind::InvalidValue).
280 fn try_from(raw: igraph_edge_type_sw_t) -> crate::error::Result<Self> {
281 [Self::SIMPLE, Self::LOOPS, Self::MULTI, Self::ALL]
282 .into_iter()
283 .find(|t| t.to_raw() == raw)
284 .ok_or_else(|| {
285 crate::error::Error::invalid(format!("invalid value {raw} for AllowedEdgeTypes"))
286 })
287 }
288}
289
290impl std::ops::BitOr for AllowedEdgeTypes {
291 type Output = Self;
292 fn bitor(self, rhs: Self) -> Self {
293 Self {
294 loops: self.loops || rhs.loops,
295 multi: self.multi || rhs.multi,
296 }
297 }
298}
299
300impl std::ops::BitOr<EdgeTypeSw> for AllowedEdgeTypes {
301 type Output = Self;
302 fn bitor(self, rhs: EdgeTypeSw) -> Self {
303 self | Self::from(rhs)
304 }
305}
306
307impl std::ops::BitOr for EdgeTypeSw {
308 type Output = AllowedEdgeTypes;
309 fn bitor(self, rhs: Self) -> AllowedEdgeTypes {
310 AllowedEdgeTypes::from(self) | AllowedEdgeTypes::from(rhs)
311 }
312}
313
314/// Former name of [`EdgeTypeSw`], kept for backwards compatibility.
315#[deprecated(note = "use `EdgeTypeSw`")]
316#[allow(non_camel_case_types)]
317pub type edge_type_sw_t = EdgeTypeSw;
318
319ffi_enum! {
320 /// Sorting order (`igraph_order_t`).
321 pub enum Order: igraph_order_t {
322 /// Ascending.
323 Ascending = igraph_order_t_IGRAPH_ASCENDING,
324 /// Descending.
325 Descending = igraph_order_t_IGRAPH_DESCENDING,
326 }
327}
328
329ffi_enum! {
330 /// Weak or strong connectedness (`igraph_connectedness_t`).
331 pub enum Connectedness: igraph_connectedness_t {
332 /// Ignore edge directions.
333 Weak = igraph_connectedness_t_IGRAPH_WEAK,
334 /// Require directed paths in both directions.
335 Strong = igraph_connectedness_t_IGRAPH_STRONG,
336 }
337}
338
339ffi_enum! {
340 /// Reciprocity definition (`igraph_reciprocity_t`).
341 pub enum Reciprocity: igraph_reciprocity_t {
342 /// Ratio of reciprocated edges to all edges.
343 Default = igraph_reciprocity_t_IGRAPH_RECIPROCITY_DEFAULT,
344 /// Ratio of mutual vertex pairs to connected vertex pairs.
345 Ratio = igraph_reciprocity_t_IGRAPH_RECIPROCITY_RATIO,
346 }
347}
348
349ffi_enum! {
350 /// How to interpret an adjacency matrix (`igraph_adjacency_t`).
351 pub enum Adjacency: igraph_adjacency_t {
352 /// Directed graph, `A[i][j]` edges from `i` to `j`.
353 Directed = igraph_adjacency_t_IGRAPH_ADJ_DIRECTED,
354 /// Undirected graph, the matrix must be symmetric.
355 Undirected = igraph_adjacency_t_IGRAPH_ADJ_UNDIRECTED,
356 /// Undirected graph from the upper triangle.
357 Upper = igraph_adjacency_t_IGRAPH_ADJ_UPPER,
358 /// Undirected graph from the lower triangle.
359 Lower = igraph_adjacency_t_IGRAPH_ADJ_LOWER,
360 /// Undirected graph, `min(A[i][j], A[j][i])` edges.
361 Min = igraph_adjacency_t_IGRAPH_ADJ_MIN,
362 /// Undirected graph, `A[i][j] + A[j][i]` edges.
363 Plus = igraph_adjacency_t_IGRAPH_ADJ_PLUS,
364 /// Undirected graph, `max(A[i][j], A[j][i])` edges.
365 Max = igraph_adjacency_t_IGRAPH_ADJ_MAX,
366 }
367}
368
369ffi_enum! {
370 /// Orientation of a star graph (`igraph_star_mode_t`).
371 pub enum StarMode: igraph_star_mode_t {
372 /// Edges point from the center outwards.
373 Out = igraph_star_mode_t_IGRAPH_STAR_OUT,
374 /// Edges point to the center.
375 In = igraph_star_mode_t_IGRAPH_STAR_IN,
376 /// Undirected star.
377 Undirected = igraph_star_mode_t_IGRAPH_STAR_UNDIRECTED,
378 /// Mutual directed edges.
379 Mutual = igraph_star_mode_t_IGRAPH_STAR_MUTUAL,
380 }
381}
382
383ffi_enum! {
384 /// Orientation of a wheel graph (`igraph_wheel_mode_t`).
385 pub enum WheelMode: igraph_wheel_mode_t {
386 /// Spokes point from the center outwards.
387 Out = igraph_wheel_mode_t_IGRAPH_WHEEL_OUT,
388 /// Spokes point to the center.
389 In = igraph_wheel_mode_t_IGRAPH_WHEEL_IN,
390 /// Undirected wheel.
391 Undirected = igraph_wheel_mode_t_IGRAPH_WHEEL_UNDIRECTED,
392 /// Mutual directed edges.
393 Mutual = igraph_wheel_mode_t_IGRAPH_WHEEL_MUTUAL,
394 }
395}
396
397ffi_enum! {
398 /// Orientation of a tree (`igraph_tree_mode_t`).
399 pub enum TreeMode: igraph_tree_mode_t {
400 /// Edges point away from the root.
401 Out = igraph_tree_mode_t_IGRAPH_TREE_OUT,
402 /// Edges point towards the root.
403 In = igraph_tree_mode_t_IGRAPH_TREE_IN,
404 /// Undirected tree.
405 Undirected = igraph_tree_mode_t_IGRAPH_TREE_UNDIRECTED,
406 }
407}
408
409ffi_enum! {
410 /// Which part of the adjacency matrix to produce for undirected graphs
411 /// (`igraph_get_adjacency_t`).
412 pub enum GetAdjacency: igraph_get_adjacency_t {
413 /// Upper triangle only.
414 Upper = igraph_get_adjacency_t_IGRAPH_GET_ADJACENCY_UPPER,
415 /// Lower triangle only.
416 Lower = igraph_get_adjacency_t_IGRAPH_GET_ADJACENCY_LOWER,
417 /// Full symmetric matrix.
418 Both = igraph_get_adjacency_t_IGRAPH_GET_ADJACENCY_BOTH,
419 }
420}
421
422ffi_enum! {
423 /// Method for sampling graphs with a given degree sequence (`igraph_degseq_t`).
424 pub enum DegreeSequenceMethod: igraph_degseq_t {
425 /// Configuration model, may produce loops and multi-edges.
426 Configuration = igraph_degseq_t_IGRAPH_DEGSEQ_CONFIGURATION,
427 /// Viger–Latapy: undirected simple *connected* graphs, sampled
428 /// approximately uniformly (a Monte Carlo method based on
429 /// degree-preserving edge switches).
430 VigerLatapy = igraph_degseq_t_IGRAPH_DEGSEQ_VL,
431 /// Fast heuristic generating simple graphs: like the configuration
432 /// model, but avoiding loops and multi-edges and restarting when stuck
433 /// (not uniform).
434 FastHeurSimple = igraph_degseq_t_IGRAPH_DEGSEQ_FAST_HEUR_SIMPLE,
435 /// Configuration model with rejection of non-simple graphs: uniform
436 /// simple graphs (possibly slow).
437 ConfigurationSimple = igraph_degseq_t_IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE,
438 /// Edge-switching Markov chain started from a realization of the
439 /// sequence: simple (directed or undirected) graphs.
440 EdgeSwitchingSimple = igraph_degseq_t_IGRAPH_DEGSEQ_EDGE_SWITCHING_SIMPLE,
441 }
442}
443
444ffi_enum! {
445 /// Vertex choice when realizing a degree sequence (`igraph_realize_degseq_t`).
446 pub enum RealizeDegseq: igraph_realize_degseq_t {
447 /// Pick the vertex with the smallest remaining degree.
448 Smallest = igraph_realize_degseq_t_IGRAPH_REALIZE_DEGSEQ_SMALLEST,
449 /// Pick the vertex with the largest remaining degree.
450 Largest = igraph_realize_degseq_t_IGRAPH_REALIZE_DEGSEQ_LARGEST,
451 /// Pick vertices in index order.
452 Index = igraph_realize_degseq_t_IGRAPH_REALIZE_DEGSEQ_INDEX,
453 }
454}
455
456ffi_enum! {
457 /// Random tree sampling algorithm (`igraph_random_tree_t`).
458 pub enum RandomTreeMethod: igraph_random_tree_t {
459 /// Random Prüfer sequence.
460 Prufer = igraph_random_tree_t_IGRAPH_RANDOM_TREE_PRUFER,
461 /// Loop-erased random walk.
462 Lerw = igraph_random_tree_t_IGRAPH_RANDOM_TREE_LERW,
463 }
464}
465
466ffi_enum! {
467 /// Edge ordering for edge selectors (`igraph_edgeorder_type_t`).
468 pub enum EdgeOrder: igraph_edgeorder_type_t {
469 /// By edge id.
470 Id = igraph_edgeorder_type_t_IGRAPH_EDGEORDER_ID,
471 /// By source vertex.
472 From = igraph_edgeorder_type_t_IGRAPH_EDGEORDER_FROM,
473 /// By target vertex.
474 To = igraph_edgeorder_type_t_IGRAPH_EDGEORDER_TO,
475 }
476}
477
478ffi_enum! {
479 /// How to convert undirected edges to directed ones (`igraph_to_directed_t`).
480 pub enum ToDirected: igraph_to_directed_t {
481 /// One directed edge with arbitrary direction.
482 Arbitrary = igraph_to_directed_t_IGRAPH_TO_DIRECTED_ARBITRARY,
483 /// Two mutual directed edges.
484 Mutual = igraph_to_directed_t_IGRAPH_TO_DIRECTED_MUTUAL,
485 /// One directed edge with random direction.
486 Random = igraph_to_directed_t_IGRAPH_TO_DIRECTED_RANDOM,
487 /// From lower to higher vertex id, giving an acyclic graph.
488 Acyclic = igraph_to_directed_t_IGRAPH_TO_DIRECTED_ACYCLIC,
489 }
490}
491
492ffi_enum! {
493 /// How to convert directed edges to undirected ones (`igraph_to_undirected_t`).
494 pub enum ToUndirected: igraph_to_undirected_t {
495 /// Keep every edge.
496 Each = igraph_to_undirected_t_IGRAPH_TO_UNDIRECTED_EACH,
497 /// One undirected edge per connected vertex pair.
498 Collapse = igraph_to_undirected_t_IGRAPH_TO_UNDIRECTED_COLLAPSE,
499 /// One undirected edge per mutual pair.
500 Mutual = igraph_to_undirected_t_IGRAPH_TO_UNDIRECTED_MUTUAL,
501 }
502}
503
504ffi_enum! {
505 /// What to do when computing the vertex connectivity of two *adjacent*
506 /// vertices, which no vertex removal can disconnect
507 /// (`igraph_vconn_nei_t`).
508 pub enum VconnNei: igraph_vconn_nei_t {
509 /// Report an error.
510 Error = igraph_vconn_nei_t_IGRAPH_VCONN_NEI_ERROR,
511 /// Return the number of vertices.
512 NumberOfNodes = igraph_vconn_nei_t_IGRAPH_VCONN_NEI_NUMBER_OF_NODES,
513 /// Ignore the edges between them: count the vertices needed to cut
514 /// all the other paths.
515 Ignore = igraph_vconn_nei_t_IGRAPH_VCONN_NEI_IGNORE,
516 /// Return -1.
517 Negative = igraph_vconn_nei_t_IGRAPH_VCONN_NEI_NEGATIVE,
518 }
519}
520
521ffi_enum! {
522 /// Update rule of the spinglass community detection (`igraph_spincomm_update_t`).
523 pub enum SpincommUpdate: igraph_spincomm_update_t {
524 /// Simple null model.
525 Simple = igraph_spincomm_update_t_IGRAPH_SPINCOMM_UPDATE_SIMPLE,
526 /// Configuration null model.
527 Config = igraph_spincomm_update_t_IGRAPH_SPINCOMM_UPDATE_CONFIG,
528 }
529}
530
531ffi_enum! {
532 /// Value of local transitivity for vertices of degree < 2 (`igraph_transitivity_mode_t`).
533 pub enum TransitivityMode: igraph_transitivity_mode_t {
534 /// NaN.
535 Nan = igraph_transitivity_mode_t_IGRAPH_TRANSITIVITY_NAN,
536 /// Zero.
537 Zero = igraph_transitivity_mode_t_IGRAPH_TRANSITIVITY_ZERO,
538 }
539}
540
541ffi_enum! {
542 /// Spinglass implementation (`igraph_spinglass_implementation_t`).
543 pub enum SpinglassImplementation: igraph_spinglass_implementation_t {
544 /// Original implementation (positive weights only).
545 Orig = igraph_spinglass_implementation_t_IGRAPH_SPINCOMM_IMP_ORIG,
546 /// Variant supporting negative weights.
547 Neg = igraph_spinglass_implementation_t_IGRAPH_SPINCOMM_IMP_NEG,
548 }
549}
550
551ffi_enum! {
552 /// Measure used to compare two community structures (`igraph_community_comparison_t`).
553 pub enum CommunityComparison: igraph_community_comparison_t {
554 /// Variation of information.
555 Vi = igraph_community_comparison_t_IGRAPH_COMMCMP_VI,
556 /// Normalized mutual information.
557 Nmi = igraph_community_comparison_t_IGRAPH_COMMCMP_NMI,
558 /// Split-join distance.
559 SplitJoin = igraph_community_comparison_t_IGRAPH_COMMCMP_SPLIT_JOIN,
560 /// Rand index.
561 Rand = igraph_community_comparison_t_IGRAPH_COMMCMP_RAND,
562 /// Adjusted Rand index.
563 AdjustedRand = igraph_community_comparison_t_IGRAPH_COMMCMP_ADJUSTED_RAND,
564 }
565}
566
567ffi_enum! {
568 /// Whether to add weights when converting from matrices (`igraph_add_weights_t`).
569 pub enum AddWeights: igraph_add_weights_t {
570 /// No weights.
571 No = igraph_add_weights_t_IGRAPH_ADD_WEIGHTS_NO,
572 /// Add weights.
573 Yes = igraph_add_weights_t_IGRAPH_ADD_WEIGHTS_YES,
574 /// Add weights if present.
575 IfPresent = igraph_add_weights_t_IGRAPH_ADD_WEIGHTS_IF_PRESENT,
576 }
577}
578
579ffi_enum! {
580 /// Algorithm of the Barabási–Albert generator (`igraph_barabasi_algorithm_t`).
581 pub enum BarabasiAlgorithm: igraph_barabasi_algorithm_t {
582 /// Bag algorithm (may produce multi-edges).
583 Bag = igraph_barabasi_algorithm_t_IGRAPH_BARABASI_BAG,
584 /// Partial prefix-sum tree, simple graphs.
585 Psumtree = igraph_barabasi_algorithm_t_IGRAPH_BARABASI_PSUMTREE,
586 /// Partial prefix-sum tree, multi-edges allowed.
587 PsumtreeMultiple = igraph_barabasi_algorithm_t_IGRAPH_BARABASI_PSUMTREE_MULTIPLE,
588 }
589}
590
591ffi_enum! {
592 /// Feedback arc set algorithm (`igraph_fas_algorithm_t`).
593 pub enum FasAlgorithm: igraph_fas_algorithm_t {
594 /// Minimum feedback arc set by integer programming, letting igraph
595 /// pick the best such method (currently [`FasAlgorithm::ExactIpCg`]).
596 ExactIp = igraph_fas_algorithm_t_IGRAPH_FAS_EXACT_IP,
597 /// Eades–Lin–Smyth heuristic: linear time, at most `|E|/2 - |V|/6`
598 /// edges, not necessarily minimum.
599 ApproxEades = igraph_fas_algorithm_t_IGRAPH_FAS_APPROX_EADES,
600 /// Exact integer programming on a set cover formulation, with
601 /// incremental generation of cycle constraints.
602 ExactIpCg = igraph_fas_algorithm_t_IGRAPH_FAS_EXACT_IP_CG,
603 /// Exact integer programming on a topological order formulation with
604 /// triangle inequalities (typically much slower than
605 /// [`FasAlgorithm::ExactIpCg`]).
606 ExactIpTi = igraph_fas_algorithm_t_IGRAPH_FAS_EXACT_IP_TI,
607 }
608}
609
610ffi_enum! {
611 /// Feedback vertex set algorithm (`igraph_fvs_algorithm_t`).
612 pub enum FvsAlgorithm: igraph_fvs_algorithm_t {
613 /// Exact integer programming.
614 ExactIp = igraph_fvs_algorithm_t_IGRAPH_FVS_EXACT_IP,
615 }
616}
617
618ffi_enum! {
619 /// Implementation strategy for induced subgraphs (`igraph_subgraph_implementation_t`).
620 pub enum SubgraphImplementation: igraph_subgraph_implementation_t {
621 /// Let igraph decide.
622 Auto = igraph_subgraph_implementation_t_IGRAPH_SUBGRAPH_AUTO,
623 /// Copy the graph and delete vertices.
624 CopyAndDelete = igraph_subgraph_implementation_t_IGRAPH_SUBGRAPH_COPY_AND_DELETE,
625 /// Build the subgraph from scratch.
626 CreateFromScratch = igraph_subgraph_implementation_t_IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH,
627 }
628}
629
630ffi_enum! {
631 /// Whether force-directed layouts use a grid (`igraph_layout_grid_t`).
632 pub enum LayoutGrid: igraph_layout_grid_t {
633 /// Use a grid.
634 Grid = igraph_layout_grid_t_IGRAPH_LAYOUT_GRID,
635 /// Do not use a grid.
636 NoGrid = igraph_layout_grid_t_IGRAPH_LAYOUT_NOGRID,
637 /// Use a grid for large graphs only.
638 AutoGrid = igraph_layout_grid_t_IGRAPH_LAYOUT_AUTOGRID,
639 }
640}
641
642ffi_enum! {
643 /// What a random walk does when stuck (`igraph_random_walk_stuck_t`).
644 pub enum RandomWalkStuck: igraph_random_walk_stuck_t {
645 /// Report an error.
646 Error = igraph_random_walk_stuck_t_IGRAPH_RANDOM_WALK_STUCK_ERROR,
647 /// Return the walk so far.
648 Return = igraph_random_walk_stuck_t_IGRAPH_RANDOM_WALK_STUCK_RETURN,
649 }
650}
651
652ffi_enum! {
653 /// Tie breaking in Voronoi partitioning (`igraph_voronoi_tiebreaker_t`).
654 pub enum VoronoiTiebreaker: igraph_voronoi_tiebreaker_t {
655 /// First generator.
656 First = igraph_voronoi_tiebreaker_t_IGRAPH_VORONOI_FIRST,
657 /// Last generator.
658 Last = igraph_voronoi_tiebreaker_t_IGRAPH_VORONOI_LAST,
659 /// Random generator.
660 Random = igraph_voronoi_tiebreaker_t_IGRAPH_VORONOI_RANDOM,
661 }
662}
663
664ffi_enum! {
665 /// Variant of the Chung–Lu model (`igraph_chung_lu_t`).
666 pub enum ChungLuVariant: igraph_chung_lu_t {
667 /// Original model.
668 Original = igraph_chung_lu_t_IGRAPH_CHUNG_LU_ORIGINAL,
669 /// Maximum entropy variant.
670 MaxEnt = igraph_chung_lu_t_IGRAPH_CHUNG_LU_MAXENT,
671 /// Norros–Reittu variant.
672 Nr = igraph_chung_lu_t_IGRAPH_CHUNG_LU_NR,
673 }
674}
675
676ffi_enum! {
677 /// Storage order of matrices given as flat arrays (`igraph_matrix_storage_t`).
678 pub enum MatrixStorage: igraph_matrix_storage_t {
679 /// Row-major.
680 RowMajor = igraph_matrix_storage_t_IGRAPH_ROW_MAJOR,
681 /// Column-major.
682 ColumnMajor = igraph_matrix_storage_t_IGRAPH_COLUMN_MAJOR,
683 }
684}
685
686ffi_enum! {
687 /// Minimum spanning tree algorithm (`igraph_mst_algorithm_t`).
688 pub enum MstAlgorithm: igraph_mst_algorithm_t {
689 /// Let igraph choose.
690 Automatic = igraph_mst_algorithm_t_IGRAPH_MST_AUTOMATIC,
691 /// Unweighted (BFS based).
692 Unweighted = igraph_mst_algorithm_t_IGRAPH_MST_UNWEIGHTED,
693 /// Prim's algorithm.
694 Prim = igraph_mst_algorithm_t_IGRAPH_MST_PRIM,
695 /// Kruskal's algorithm.
696 Kruskal = igraph_mst_algorithm_t_IGRAPH_MST_KRUSKAL,
697 }
698}
699
700ffi_enum! {
701 /// Kind of graph product (`igraph_product_t`).
702 pub enum Product: igraph_product_t {
703 /// Cartesian product.
704 Cartesian = igraph_product_t_IGRAPH_PRODUCT_CARTESIAN,
705 /// Lexicographic product.
706 Lexicographic = igraph_product_t_IGRAPH_PRODUCT_LEXICOGRAPHIC,
707 /// Strong product.
708 Strong = igraph_product_t_IGRAPH_PRODUCT_STRONG,
709 /// Tensor (categorical) product.
710 Tensor = igraph_product_t_IGRAPH_PRODUCT_TENSOR,
711 /// Modular product.
712 Modular = igraph_product_t_IGRAPH_PRODUCT_MODULAR,
713 }
714}
715
716ffi_enum! {
717 /// Label propagation variant (`igraph_lpa_variant_t`).
718 pub enum LpaVariant: igraph_lpa_variant_t {
719 /// Sample from the dominant labels, and check the dominance of all
720 /// vertices after each iteration.
721 Dominance = igraph_lpa_variant_t_IGRAPH_LPA_DOMINANCE,
722 /// Keep the current label if it is among the dominant ones; only
723 /// check the vertices whose labels changed.
724 Retention = igraph_lpa_variant_t_IGRAPH_LPA_RETENTION,
725 /// Sample from the dominant labels, only checking neighbors (fast).
726 Fast = igraph_lpa_variant_t_IGRAPH_LPA_FAST,
727 }
728}