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
use super::{EdgeType, Pattern, Result};
use smile::autocxx::c_int;
/// A node in a [Pattern]
pub struct PatternNode<'a> {
pub(super) index: usize,
pub(super) pattern: &'a Pattern,
}
impl PatternNode<'_> {
/// Get the index of the node
pub fn get_index(&self) -> usize {
self.index
}
/// Get the indices of parents of the node
// TODO: Add example
pub fn get_parent_indices(&self) -> Vec<usize> {
// TODO: This method did not compile due to CxxVector<T> not being able to hold c_* types.
// see: https://github.com/google/autocxx/issues/422
// see: https://github.com/dtolnay/cxx/pull/874
// let mut parents = vec![];
// self.pattern.dsl_pattern.as_ref().GetParents(self.index, parents);
// If the node does not have an incoming edge, it does not have parents
if !self.has_incoming_edge() {
return vec![];
}
(0..self.pattern.get_node_count())
.filter(|&i| {
self.pattern.get_edge(i, self.index) == Ok(EdgeType::Directed(i, self.index))
})
.collect()
}
/// Get the parents of the node
pub fn get_parents(&self) -> Result<Vec<PatternNode>> {
self.get_parent_indices()
.iter()
.map(|&index| self.pattern.get_node(index))
.collect()
}
/// Get the indices of children of the node
// TODO: Add example
pub fn get_child_indices(&self) -> Vec<usize> {
// TODO: This method did not compile due to CxxVector<T> not being able to hold c_* types.
// see: https://github.com/google/autocxx/issues/422
// see: https://github.com/dtolnay/cxx/pull/874
// let mut children = vec![];
// self.pattern.dsl_pattern.as_ref().GetChildren(self.index, children);
// If the node does not have an outgoing edge, it does not have children
if !self.has_outgoing_edge() {
return vec![];
}
(0..self.pattern.get_node_count())
.filter(|&i| {
self.pattern.get_edge(self.index, i) == Ok(EdgeType::Directed(self.index, i))
})
.collect()
}
/// Get the children of the node
pub fn get_children(&self) -> Result<Vec<PatternNode>> {
self.get_child_indices()
.iter()
.map(|&index| self.pattern.get_node(index))
.collect()
}
/// Get the indices of adjacent nodes to the node
// TODO: Add example
pub fn get_adjacent_indices(&self) -> Vec<usize> {
// TODO: This method did not compile due to CxxVector<T> not being able to hold c_* types.
// see: https://github.com/google/autocxx/issues/422
// see: https://github.com/dtolnay/cxx/pull/874
// let mut adjacent = vec![];
// self.pattern.dsl_pattern.as_ref().GetAdjacentNodes(self.index, adjacent);
(0..self.pattern.get_node_count())
.filter(|&i| {
let edge_type = self.pattern.get_edge(self.index, i);
edge_type == Ok(EdgeType::Directed(self.index, i))
|| edge_type == Ok(EdgeType::Undirected)
})
.collect()
}
/// Get the adjacent nodes to the node
pub fn get_adjacent_nodes(&self) -> Result<Vec<PatternNode>> {
self.get_adjacent_indices()
.iter()
.map(|&index| self.pattern.get_node(index))
.collect()
}
/// Check if the node has an incoming edge
pub fn has_incoming_edge(&self) -> bool {
self.pattern
.dsl_pattern
.as_ref()
.HasIncomingEdge(c_int(self.index as i32))
}
/// Check if the node has an outgoing edge
pub fn has_outgoing_edge(&self) -> bool {
self.pattern
.dsl_pattern
.as_ref()
.HasOutgoingEdge(c_int(self.index as i32))
}
}