Packages
rbt_weave
0.2.61
0.2.67
0.2.66
0.2.65
0.2.64
0.2.63
0.2.62
0.2.61
0.2.60
0.2.59
0.2.58
0.2.57
0.2.56
0.2.55
0.2.54
0.2.53
0.2.52
0.2.51
0.2.50
0.2.49
0.2.48
0.2.47
0.2.46
0.2.45
0.2.44
0.2.43
0.2.42
0.2.41
0.2.40
0.2.39
0.2.38
0.2.37
0.2.36
0.2.35
0.2.34
0.2.33
0.2.32
0.2.31
0.2.30
0.2.29
0.2.28
0.2.27
0.2.26
0.2.25
0.2.24
0.2.23
0.2.22
0.2.21
0.2.20
0.2.19
0.2.18
0.2.17
0.2.16
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Graph conflict detection and image processing NIFs for OSINT knowledge graphs, powered by Rust.
Current section
Files
Jump to
Current section
Files
nif/src/lib.rs
#![allow(clippy::needless_pass_by_value)]
use std::collections::HashSet;
use serde::Deserialize;
use weave_graph::detect::DetectOpts;
use weave_graph::graph::{IndexedSubgraph, Subgraph};
/// NIF options passed from Elixir as JSON.
#[derive(Debug, Default, Deserialize)]
struct NifOpts {
#[serde(default = "default_max_depth")]
max_depth: usize,
#[serde(default)]
patterns: Option<Vec<String>>,
}
fn default_max_depth() -> usize {
6
}
#[rustler::nif]
fn health_check() -> String {
String::from("ok")
}
/// Detect conflict-of-interest patterns in a subgraph.
///
/// Takes a JSON-serialized `Subgraph` and an optional JSON options
/// string. Returns a JSON-serialized list of `ConflictPattern`s.
#[rustler::nif(schedule = "DirtyCpu")]
fn detect_conflicts(subgraph_json: String, opts_json: String) -> Result<String, String> {
let subgraph: Subgraph =
serde_json::from_str(&subgraph_json).map_err(|e| format!("invalid subgraph: {e}"))?;
let nif_opts: NifOpts =
serde_json::from_str(&opts_json).map_err(|e| format!("invalid opts: {e}"))?;
let detect_opts = DetectOpts {
max_depth: nif_opts.max_depth,
pattern_ids: nif_opts
.patterns
.map(|ps| ps.into_iter().collect::<HashSet<_>>()),
};
let indexed = IndexedSubgraph::from_subgraph(&subgraph);
let results = weave_graph::detect::detect_conflicts(&indexed, &detect_opts);
serde_json::to_string(&results).map_err(|e| format!("serialization error: {e}"))
}
/// Compute the thumbnail storage key from a source URL.
///
/// Returns `thumbnails/{sha256_hex(url)[0..32]}.webp`.
#[rustler::nif]
fn thumbnail_key(source_url: String) -> String {
weave_image::thumbnail_key(&source_url)
}
/// Download an image, resize to 256x256 WebP thumbnail, and compute
/// the storage key.
///
/// Returns `{key, webp_bytes}` on success or an error string.
#[rustler::nif(schedule = "DirtyCpu")]
fn process_thumbnail(url: String) -> Result<(String, Vec<u8>), String> {
let result = weave_image::process_thumbnail(&url).map_err(|e| e.to_string())?;
Ok((result.key, result.data))
}
/// Static country names JSON embedded at compile time.
const COUNTRY_NAMES_JSON: &str = include_str!("../../crates/weave-content/countries.json");
/// Return the country names map as a JSON string.
/// This provides a single source of truth for country code to name mapping.
#[rustler::nif]
fn country_names() -> String {
COUNTRY_NAMES_JSON.to_string()
}
rustler::init!("Elixir.Weave.Native");