weavatrix-rust 2.16.0

Protocol-independent Rust repository intelligence: typed evidence graphs for impact, architecture, APIs, Git, search, and memory
Documentation
use blazingly_json::Value;

fn arg_value<'value, T>(
    args: &'value Value,
    key: &str,
    expected: &str,
    extract: impl FnOnce(&'value Value) -> Option<T>,
) -> Result<T, String> {
    args.get(key)
        .and_then(extract)
        .ok_or_else(|| format!("{key} must be {expected}"))
}

pub(crate) fn arg_str<'value>(args: &'value Value, key: &str) -> Result<&'value str, String> {
    arg_value(args, key, "a string", Value::as_str)
}

pub(crate) fn arg_u64(args: &Value, key: &str) -> Result<u64, String> {
    arg_value(args, key, "a non-negative integer", Value::as_u64)
}

pub(crate) fn arg_bool(args: &Value, key: &str) -> Result<bool, String> {
    arg_value(args, key, "a boolean", Value::as_bool)
}

pub(crate) fn optional_str<'value>(
    args: &'value Value,
    key: &str,
) -> Result<Option<&'value str>, String> {
    args.get(key)
        .map(|value| {
            value
                .as_str()
                .ok_or_else(|| format!("{key} must be a string"))
        })
        .transpose()
}

pub(crate) fn optional_u64(args: &Value, key: &str) -> Result<Option<u64>, String> {
    args.get(key)
        .map(|value| {
            value
                .as_u64()
                .ok_or_else(|| format!("{key} must be a non-negative integer"))
        })
        .transpose()
}

pub(crate) fn optional_bool(args: &Value, key: &str) -> Result<Option<bool>, String> {
    args.get(key)
        .map(|value| {
            value
                .as_bool()
                .ok_or_else(|| format!("{key} must be a boolean"))
        })
        .transpose()
}

pub(crate) fn require_graph_precision(args: &Value) -> Result<(), String> {
    let Some(precision) = optional_str(args, "precision")? else {
        return Ok(());
    };
    if precision == "graph" {
        return Ok(());
    }
    Err(format!(
        "precision '{precision}' is unsupported; this operation supports only 'graph' bounded static precision"
    ))
}

#[cfg(any(feature = "semantic", feature = "vector"))]
pub(super) fn vector_values(value: &Value, array_error: &str) -> Result<Vec<f32>, String> {
    value
        .as_array()
        .ok_or_else(|| array_error.to_owned())?
        .iter()
        .map(|value| {
            let value = value
                .as_f64()
                .filter(|value| value.is_finite())
                .ok_or_else(|| "vector value must be finite".to_owned())?;
            if !(f64::from(f32::MIN)..=f64::from(f32::MAX)).contains(&value) {
                return Err("vector value is outside finite f32 range".to_owned());
            }
            value
                .to_string()
                .parse::<f32>()
                .map_err(|error| format!("invalid vector value: {error}"))
        })
        .collect()
}