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#[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#[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#[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#[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#[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#[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#[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#[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#[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}