graphannis_capi/
graph.rs

1use super::{cast_const, cstr};
2use crate::{cerror::ErrorList, data::IterPtr, map_cerr};
3use graphannis::{
4    AnnotationGraph,
5    errors::GraphAnnisError,
6    graph::{Annotation, Edge, Match, NodeID},
7    model::{AnnotationComponent, AnnotationComponentType},
8};
9use itertools::Itertools;
10use std::ffi::CString;
11
12/// Get the type of the given component.
13#[unsafe(no_mangle)]
14pub extern "C" fn annis_component_type(c: *const AnnotationComponent) -> AnnotationComponentType {
15    let c: &AnnotationComponent = cast_const(c);
16    c.get_type()
17}
18
19/// Get the layer of the given component.
20///
21/// The returned string must be deallocated by the caller using annis_str_free()!
22#[unsafe(no_mangle)]
23pub extern "C" fn annis_component_layer(c: *const AnnotationComponent) -> *mut libc::c_char {
24    let c: &AnnotationComponent = cast_const(c);
25    let as_string: &str = &c.layer;
26    CString::new(as_string).unwrap_or_default().into_raw()
27}
28
29/// Get the name of the given component.
30///
31/// The returned string must be deallocated by the caller using annis_str_free()!
32#[unsafe(no_mangle)]
33pub extern "C" fn annis_component_name(c: *const AnnotationComponent) -> *mut libc::c_char {
34    let c: &AnnotationComponent = cast_const(c);
35    let as_string: &str = &c.name;
36    CString::new(as_string).unwrap_or_default().into_raw()
37}
38
39/// Return an iterator over all nodes of the graph `g` and the given `node_type` (e.g. "node" or "corpus").
40#[unsafe(no_mangle)]
41pub extern "C" fn annis_graph_nodes_by_type(
42    g: *const AnnotationGraph,
43    node_type: *const libc::c_char,
44) -> *mut IterPtr<NodeID> {
45    let db: &AnnotationGraph = cast_const(g);
46    let node_type = cstr(node_type);
47    let it = db
48        .get_node_annos()
49        .exact_anno_search(Some("annis"), "node_type", Some(node_type.as_ref()).into())
50        .map_ok(|m: Match| m.node)
51        .map(|n| n.map_err(GraphAnnisError::from));
52    Box::into_raw(Box::new(Box::new(it)))
53}
54
55/// Return a vector of all annotations for the given `node` in the graph `g`.
56///
57/// - `err` - Pointer to a list of errors. If any error occured, this list will be non-empty.
58#[unsafe(no_mangle)]
59pub extern "C" fn annis_graph_annotations_for_node(
60    g: *const AnnotationGraph,
61    node: NodeID,
62    err: *mut *mut ErrorList,
63) -> *mut Vec<Annotation> {
64    let db: &AnnotationGraph = cast_const(g);
65
66    map_cerr(db.get_node_annos().get_annotations_for_item(&node), err)
67        .map(|annos| {
68            let anno = Box::new(annos);
69            Box::into_raw(anno)
70        })
71        .unwrap_or_else(std::ptr::null_mut)
72}
73
74/// Return a vector of all components for the graph `g`.
75#[unsafe(no_mangle)]
76pub extern "C" fn annis_graph_all_components(
77    g: *const AnnotationGraph,
78) -> *mut Vec<AnnotationComponent> {
79    let db: &AnnotationGraph = cast_const(g);
80
81    Box::into_raw(Box::new(db.get_all_components(None, None)))
82}
83
84/// Return a vector of all components for the graph `g` and the given component type.
85#[unsafe(no_mangle)]
86pub extern "C" fn annis_graph_all_components_by_type(
87    g: *const AnnotationGraph,
88    ctype: AnnotationComponentType,
89) -> *mut Vec<AnnotationComponent> {
90    let db: &AnnotationGraph = cast_const(g);
91
92    Box::into_raw(Box::new(db.get_all_components(Some(ctype), None)))
93}
94
95/// Return a vector of all outgoing edges for the graph `g`, the `source` node and the given `component`.
96///
97/// - `err` - Pointer to a list of errors. If any error occured, this list will be non-empty.
98#[unsafe(no_mangle)]
99pub extern "C" fn annis_graph_outgoing_edges(
100    g: *const AnnotationGraph,
101    source: NodeID,
102    component: *const AnnotationComponent,
103    err: *mut *mut ErrorList,
104) -> *mut Vec<Edge> {
105    let db: &AnnotationGraph = cast_const(g);
106    let component: &AnnotationComponent = cast_const(component);
107
108    let mut result: Vec<Edge> = Vec::new();
109
110    if let Some(gs) = db.get_graphstorage(component) {
111        for target in gs.get_outgoing_edges(source) {
112            if let Some(target) = map_cerr(target, err) {
113                result.push(Edge { source, target })
114            }
115        }
116    }
117
118    Box::into_raw(Box::new(result))
119}
120
121/// Return a vector of annnotations for the given `edge` in the `component` of graph `g.
122///
123/// - `err` - Pointer to a list of errors. If any error occured, this list will be non-empty.
124#[unsafe(no_mangle)]
125pub extern "C" fn annis_graph_annotations_for_edge(
126    g: *const AnnotationGraph,
127    edge: Edge,
128    component: *const AnnotationComponent,
129    err: *mut *mut ErrorList,
130) -> *mut Vec<Annotation> {
131    let db: &AnnotationGraph = cast_const(g);
132    let component: &AnnotationComponent = cast_const(component);
133
134    if let Some(gs) = db.get_graphstorage(component) {
135        map_cerr(gs.get_anno_storage().get_annotations_for_item(&edge), err)
136            .map(|annos| Box::into_raw(Box::new(annos)))
137            .unwrap_or_else(std::ptr::null_mut)
138    } else {
139        Box::into_raw(Box::default())
140    }
141}