/// Internal namespace. pub( crate ) mod private { use crate::prelude::*; macro_rules! NODE_ID { () => { < < Self as GraphNodesNominalInterface >::NodeHandle as HasId >::Id }; } macro_rules! EDGE_ID { () => { < < Self as GraphEdgesNominalInterface >::EdgeHandle as HasId >::Id }; } /// /// Graph which know how to iterate neighbourhood of a node and capable to convert id of a node into a node. /// pub trait GraphNodesNominalInterface { /// Handle of a node - entity representing a node or the node itself. /// It's not always possible to operate a node directly, for example it it has to be wrapped by cell ref. For that use NodeHandle. /// Otherwise NodeHandle could be &Node. type NodeHandle : NodeBasicInterface; /// Convert argument into node id. #[ allow( non_snake_case ) ] #[ inline ] fn NodeId< Id >( id : Id ) -> NODE_ID!() where Id : Into< NODE_ID!() > { id.into() } /// Convert argument into node id. #[ inline ] fn node_id< Id >( &self, id : Id ) -> NODE_ID!() where Id : Into< NODE_ID!() > { id.into() } /// Get node with id. fn node< Id >( &self, id : Id ) -> &Self::NodeHandle where Id : Into< NODE_ID!() > ; /// Iterate over neighbourhood of the node. Callback gets ids of nodes in neighbourhood of a picked node. fn out_nodes_ids< 'a, 'b, Id >( &'a self, node_id : Id ) -> Box< dyn Iterator< Item = NODE_ID!() > + 'b > where Id : Into< NODE_ID!() >, 'a : 'b, ; /// Iterate over neighbourhood of the node. Callback gets ids and reference on itself of nodes in neighbourhood of a picked node. fn out_nodes< 'a, 'b, Id >( &'a self, node_id : Id ) -> Box< dyn Iterator< Item = ( NODE_ID!(), &< Self as GraphNodesNominalInterface >::NodeHandle ) > + 'b > where Id : Into< NODE_ID!() >, 'a : 'b, { Box::new( self.out_nodes_ids( node_id ).map( | id | { ( id, self.node( id ) ) })) } } /// /// Graph which know how to iterate neighbourhood of a node and capable to convert id of a node into a node. /// pub trait GraphEdgesNominalInterface where Self : GraphNodesNominalInterface, { /// Handle of an edge - entity representing an edge or the edge itself. /// It's not always possible to operate an edge directly, for example it it has to be wrapped by cell ref. For that use NodeHandle. /// Otherwise EdgeHandle could be &Node. type EdgeHandle : EdgeBasicInterface; /// Convert argument into edge id. #[ allow( non_snake_case ) ] #[ inline ] fn EdgeId< Id >( id : Id ) -> EDGE_ID!() where Id : Into< EDGE_ID!() > { id.into() } /// Convert argument into edge id. #[ inline ] fn edge_id< Id >( &self, id : Id ) -> EDGE_ID!() where Id : Into< EDGE_ID!() > { Self::EdgeId( id ) } // xxx // /// Convert argument into edges ids. // #[ allow( non_snake_case ) ] // #[ inline ] // fn EdgesIds< In, Out >( src : In< EDGE_ID!() > ) -> Out< EDGE_ID!() > // where // In : IdsFromCollection, // Out : IdsCollection, // { // src.into() // } // // /// Get edges with ids. // #[ inline ] // fn edges_ids< In, Out >( &self, src : In< EDGE_ID!() > ) -> Out< EDGE_ID!() > // where // In : IdsFromCollection, // Out : IdsCollection, // { // Self::EdgesIds( src ) // } /// Get edge with id. fn edge< Id >( &self, id : Id ) -> &Self::EdgeHandle where Id : Into< EDGE_ID!() > ; /// Iterate over output edges of the node. Callback gets ids of nodes in neighbourhood of a picked node. fn out_edges_ids< 'a, 'b, IntoId >( &'a self, node_id : IntoId ) -> Box< dyn Iterator< Item = EDGE_ID!() > + 'b > where IntoId : Into< NODE_ID!() >, 'a : 'b, ; /// Iterate over output edges of the node. Callback gets ids and references of edges in neighbourhood of a picked node. fn out_edges< 'a, 'b, IntoId >( &'a self, node_id : IntoId ) -> Box< dyn Iterator< Item = ( EDGE_ID!(), &< Self as GraphEdgesNominalInterface >::EdgeHandle ) > + 'b > where IntoId : Into< NODE_ID!() >, 'a : 'b, { Box::new( self.out_edges_ids( node_id ).map( | id | { ( id, self.edge( id ) ) })) } } /// /// Graph nodes of which is possible to enumerate. /// // pub trait GraphNodesEnumerableInterface< 'it, 'it2, It > pub trait GraphNodesEnumerableInterface where Self : GraphNodesNominalInterface, // It : Iterator< Item = &'it2 ( NODE_ID!(), &'it < Self as GraphNodesNominalInterface >::NodeHandle ) >, // < Self as GraphNodesNominalInterface >::NodeHandle : 'it, // 'it : 'it2, { /// Iterate over all nodes. fn nodes< 'a, 'b >( &'a self ) -> Box< dyn Iterator< Item = ( NODE_ID!(), &< Self as GraphNodesNominalInterface >::NodeHandle ) > + 'b > // It where 'a : 'b, ; /// Number of nodes. Order of the graph. fn nnodes( &self ) -> usize { self.nodes().count() } } /// /// Graph edges of which is possible to enumerate. /// pub trait GraphEdgesEnumerableInterface where Self : GraphNodesNominalInterface + GraphEdgesNominalInterface + , { /// Iterate over all edges. fn edges< 'a, 'b >( &'a self ) -> Box< dyn Iterator< Item = ( EDGE_ID!(), &< Self as GraphEdgesNominalInterface >::EdgeHandle ) > + 'b > where 'a : 'b, ; /// Number of edges. Size of the graph. fn nedges( &self ) -> usize { self.edges().count() } } /// /// Graph interface which allow to add more nodes. Know nothing about edges. /// pub trait GraphNodesExtendableInterface where Self : GraphNodesNominalInterface + , { /// Get node with id mutably. fn node_mut< Id >( &mut self, id : Id ) -> &mut Self::NodeHandle where Id : Into< NODE_ID!() > ; /// Add out nodes to the node. fn node_add_out_nodes< IntoId1, IntoId2, Iter > ( &mut self, node_id : IntoId1, out_nodes_iter : Iter, ) where IntoId1 : Into< NODE_ID!() >, IntoId2 : Into< NODE_ID!() >, Iter : IntoIterator< Item = IntoId2 >, Iter::IntoIter : Clone, ; /// Add out edges to the node. fn node_add_out_node< IntoId1, IntoId2 > ( &mut self, node_id : IntoId1, out_node_id : IntoId2, ) where IntoId1 : Into< NODE_ID!() >, IntoId1 : Clone, IntoId2 : Into< NODE_ID!() >, IntoId2 : Clone, { self.node_add_out_nodes( node_id, core::iter::once( out_node_id ) ); } /// Either make new or get existing node. fn node_making< Id >( &mut self, id : Id ) -> NODE_ID!() where Id : Into< NODE_ID!() > ; /// Make edges. fn make_with_edge_list< IntoIter, Id >( &mut self, into_iter : IntoIter ) where Id : Into< NODE_ID!() >, IntoIter : IntoIterator< Item = Id >, IntoIter::IntoIter : core::iter::ExactSizeIterator< Item = Id >, { use wtools::iter::prelude::*; let iter = into_iter.into_iter(); debug_assert_eq!( iter.len() % 2, 0 ); for mut chunk in &iter.chunks( 2 ) { let id1 = chunk.next().unwrap().into(); let id2 = chunk.next().unwrap().into(); self.node_making( id1 ); self.node_making( id2 ); self.node_add_out_node( id1, id2 ); } } } /// /// Graph interface which allow to add more edges. /// pub trait GraphEdgesExtendableInterface where Self : GraphNodesNominalInterface + GraphEdgesNominalInterface + GraphNodesExtendableInterface + , { /// Either make new or get existing edge for specified nodes. fn _edge_id_generate( &mut self, node1 : NODE_ID!(), node2 : NODE_ID!() ) -> EDGE_ID!(); /// Either make new or get existing edge for specified nodes. fn _edge_add( &mut self, edge_id : EDGE_ID!(), node1 : NODE_ID!(), node2 : NODE_ID!() ); /// Either make new or get existing edge for specified nodes. fn _edge_make_for_nodes< IntoNodeId1, IntoNodeId2 >( &mut self, node1 : IntoNodeId1, node2 : IntoNodeId2 ) -> EDGE_ID!() where IntoNodeId1 : Into< NODE_ID!() >, IntoNodeId2 : Into< NODE_ID!() >, { let node1 = node1.into(); let node2 = node2.into(); let edge = self._edge_id_generate( node1, node2 ); self._edge_add( edge, node1, node2 ); edge } } /// /// Graph nodes of which has a kind. /// pub trait GraphNodesKindGetterInterface where Self : GraphNodesNominalInterface, { /// Enumerate kinds of the node. type NodeKind : crate::NodeKindInterface; /// Get kind of the node. fn node_kind( &self, node_id : NODE_ID!() ) -> Self::NodeKind; } /// /// Graph nodes of which has a kind. /// pub trait GraphEdgesKindGetterInterface where Self : GraphNodesNominalInterface + GraphEdgesNominalInterface + , { /// Enumerate kinds of the node. type EdgeKind : crate::EdgeKindInterface; /// Get kind of the node. fn edge_kind( &self, edge_id : EDGE_ID!() ) -> Self::EdgeKind; } } /// Protected namespace of the module. pub mod protected { pub use super::orphan::*; } pub use protected::*; /// Parented namespace of the module. pub mod orphan { pub use super::exposed::*; } /// Exposed namespace of the module. pub mod exposed { pub use super::prelude::*; } pub use exposed::*; /// Prelude to use essentials: `use my_module::prelude::*`. pub mod prelude { pub use super::private:: { GraphNodesNominalInterface, GraphEdgesNominalInterface, GraphNodesEnumerableInterface, GraphEdgesEnumerableInterface, GraphNodesExtendableInterface, GraphEdgesExtendableInterface, GraphNodesKindGetterInterface, GraphEdgesKindGetterInterface, }; }