use super::{cast_const, cstr};
use crate::{cerror::ErrorList, data::IterPtr, map_cerr};
use graphannis::{
AnnotationGraph,
errors::GraphAnnisError,
graph::{Annotation, Edge, Match, NodeID},
model::{AnnotationComponent, AnnotationComponentType},
};
use itertools::Itertools;
use std::ffi::CString;
#[unsafe(no_mangle)]
pub extern "C" fn annis_component_type(c: *const AnnotationComponent) -> AnnotationComponentType {
let c: &AnnotationComponent = cast_const(c);
c.get_type()
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_component_layer(c: *const AnnotationComponent) -> *mut libc::c_char {
let c: &AnnotationComponent = cast_const(c);
let as_string: &str = &c.layer;
CString::new(as_string).unwrap_or_default().into_raw()
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_component_name(c: *const AnnotationComponent) -> *mut libc::c_char {
let c: &AnnotationComponent = cast_const(c);
let as_string: &str = &c.name;
CString::new(as_string).unwrap_or_default().into_raw()
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_graph_nodes_by_type(
g: *const AnnotationGraph,
node_type: *const libc::c_char,
) -> *mut IterPtr<NodeID> {
let db: &AnnotationGraph = cast_const(g);
let node_type = cstr(node_type);
let it = db
.get_node_annos()
.exact_anno_search(Some("annis"), "node_type", Some(node_type.as_ref()).into())
.map_ok(|m: Match| m.node)
.map(|n| n.map_err(GraphAnnisError::from));
Box::into_raw(Box::new(Box::new(it)))
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_graph_annotations_for_node(
g: *const AnnotationGraph,
node: NodeID,
err: *mut *mut ErrorList,
) -> *mut Vec<Annotation> {
let db: &AnnotationGraph = cast_const(g);
map_cerr(db.get_node_annos().get_annotations_for_item(&node), err)
.map(|annos| {
let anno = Box::new(annos);
Box::into_raw(anno)
})
.unwrap_or_else(std::ptr::null_mut)
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_graph_all_components(
g: *const AnnotationGraph,
) -> *mut Vec<AnnotationComponent> {
let db: &AnnotationGraph = cast_const(g);
Box::into_raw(Box::new(db.get_all_components(None, None)))
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_graph_all_components_by_type(
g: *const AnnotationGraph,
ctype: AnnotationComponentType,
) -> *mut Vec<AnnotationComponent> {
let db: &AnnotationGraph = cast_const(g);
Box::into_raw(Box::new(db.get_all_components(Some(ctype), None)))
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_graph_outgoing_edges(
g: *const AnnotationGraph,
source: NodeID,
component: *const AnnotationComponent,
err: *mut *mut ErrorList,
) -> *mut Vec<Edge> {
let db: &AnnotationGraph = cast_const(g);
let component: &AnnotationComponent = cast_const(component);
let mut result: Vec<Edge> = Vec::new();
if let Some(gs) = db.get_graphstorage(component) {
for target in gs.get_outgoing_edges(source) {
if let Some(target) = map_cerr(target, err) {
result.push(Edge { source, target })
}
}
}
Box::into_raw(Box::new(result))
}
#[unsafe(no_mangle)]
pub extern "C" fn annis_graph_annotations_for_edge(
g: *const AnnotationGraph,
edge: Edge,
component: *const AnnotationComponent,
err: *mut *mut ErrorList,
) -> *mut Vec<Annotation> {
let db: &AnnotationGraph = cast_const(g);
let component: &AnnotationComponent = cast_const(component);
if let Some(gs) = db.get_graphstorage(component) {
map_cerr(gs.get_anno_storage().get_annotations_for_item(&edge), err)
.map(|annos| Box::into_raw(Box::new(annos)))
.unwrap_or_else(std::ptr::null_mut)
} else {
Box::into_raw(Box::default())
}
}