1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
use crate::IterWrapper; use std::fmt; /// What every node should be able to do pub trait Node where Self: Clone{ /// how to construct a blank object fn new_from_index(index: u32) -> Self; /// Override this, if you want to store the network fn make_string(&self) -> Option<String>; /// Override this, if you want to load the stored network fn parse_str(_to_parse: &str) -> Option<(&str, Self)> where Self: Sized; } /// Error messages #[derive(Debug, Clone)] pub enum GraphErrors{ /// ### somehow, the existing of the edge is a problem /// Did you try to add an edge, which is already present? EdgeExists, /// ### ERROR 404: Edge not found ;) /// Did you try to delete a non existing edge? EdgeDoesNotExist, } impl GraphErrors { /// get error message as `&str`, for printing etc. pub fn to_str(&self) -> &'static str { match self { GraphErrors::EdgeExists => &"EdgeExists", GraphErrors::EdgeDoesNotExist => &"EdgeDoesNotExist", } } pub(crate) fn to_sw_state(self) -> SwChangeState { SwChangeState::GError(self) } } impl fmt::Display for GraphErrors { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.to_str()) } } /// # Returned by Monte Carlo Steps /// * information about the performed step and possible errors #[derive(Debug)] pub enum SwChangeState { /// ERROR adjecency list invalid? InvalidAdjecency, /// Can not add edge twice BlockedByExistingEdge, /// Nothing happend Nothing, /// old edge: (Rewire.0, Rewire.1), new edge (Rewire.0, Rewire.2) Rewire(u32, u32, u32), /// old edge: (Reset.0, Reset.1), new edge (Reset.0, Reset.2) Reset(u32, u32, u32), /// A GraphError occurred GError(GraphErrors), } impl SwChangeState { /// checks if self is `Nothing` variant pub fn is_nothing(&self) -> bool { if let SwChangeState::Nothing = self { true }else{ false } } /// checks if self is `Nothing` or `BlockedByExistingEdge` pub fn is_nothing_or_blocked(&self) -> bool { match self { SwChangeState::Nothing | SwChangeState::BlockedByExistingEdge => true, _ => false } } /// result is equal to `!self.is_nothing_or_blocked()` pub fn not_nothing_or_blocked(&self) -> bool { match self { SwChangeState::Nothing | SwChangeState::BlockedByExistingEdge => false, _ => true } } /// # valid states: /// * `SwChangeState::Rewire(..)` /// * `SwChangeState::Reset(..)` /// * `SwChangeState::Nothing` /// * `SwChangeState::BlockedByExistingEdge` /// # invalid states: /// * `SwChangeState::InvalidAdjecency` /// * `SwChangeState::GError(..)` pub fn is_valid(&self) -> bool { match self { SwChangeState::Rewire(..) | SwChangeState::Reset(..) | SwChangeState::Nothing | SwChangeState::BlockedByExistingEdge => true, SwChangeState::InvalidAdjecency | SwChangeState::GError(..) => false, } } } /// Defines methods all adjecency containers should have /// such that `GenericGraph` can use it pub trait AdjContainer<T: Node> where Self: fmt::Display, { /// Create new instance with id fn new(id: u32, node: T) -> Self; /// # parse from str /// * tries to parse a AdjContainer from a `str`. /// * returns `None` if failed /// /// ## Returns `Option((a, b))` /// **a)** string slice beginning directly after the part, that was used to parse /// /// **b)** the `AdjContainer` resulting form the parsing fn parse_str(to_parse: &str) -> Option<(&str, Self)> where Self: Sized; /// return reference to what the AdjContainer contains fn contained<'a>(&'a self) -> &'a T; /// return mut reference to what the AdjContainer contains fn contained_mut(&mut self) -> &mut T; /// returns iterator over indices of neighbors fn neighbors<'b>(&self) -> IterWrapper; /// count number of neighbors, i.e. number of edges incident to `self` fn degree(&self) -> usize; /// returns id of container fn id(&self) -> u32; /// returns `Some(first element from the adjecency List)` or `None` fn get_adj_first(&self) -> Option<&u32>; /// check if vertex with `other_id` is adjacent to self /// ## Note: /// (in `Graph<T>`: `id` equals the index corresponding to `self`) fn is_adjacent(&self, other_id: &u32) -> bool; /// Sorting adjecency lists fn sort_adj(&mut self); /// Remove all edges /// # Important /// * will not clear edges of other AdjContainer /// * only call this if you know exactly what you are doing #[doc(hidden)] unsafe fn clear_edges(&mut self); /// # What does it do? /// Creates edge in `self` and `other`s adjecency Lists /// # Why is it unsafe? /// * No logic to see, if AdjContainer are part of the same graph /// * Only intended for internal usage /// ## What should I do? /// * use members of `net_ensembles::GenericGraph` instead, that handles the logic #[doc(hidden)] unsafe fn push(&mut self, other: &mut Self) -> Result<(), GraphErrors>; /// # What does it do? /// Removes edge in `self` and `other`s adjecency Lists /// # Why is it unsafe? /// * No logic to see, if AdjContainer are part of the same graph /// * Only intended for internal usage /// ## What should I do? /// * use members of `net_ensembles::GenericGraph` instead, that handles the logic #[doc(hidden)] unsafe fn remove(&mut self, other: &mut Self) -> Result<(), GraphErrors>; }