remem-ai 0.6.71

Local-first coding agent memory for Claude Code and OpenAI Codex
Documentation
use anyhow::{Context, Result};

pub(super) fn parse_evidence_event_ids(raw: Option<&str>, context: &str) -> Result<Vec<i64>> {
    let Some(raw) = raw.map(str::trim).filter(|value| !value.is_empty()) else {
        return Ok(Vec::new());
    };
    let mut ids = serde_json::from_str::<Vec<i64>>(raw)
        .with_context(|| format!("parse {context} for source-anchor staleness"))?;
    ids.retain(|id| *id > 0);
    ids.sort_unstable();
    ids.dedup();
    Ok(ids)
}

pub(super) fn placeholders(start: usize, count: usize) -> String {
    (start..start + count)
        .map(|index| format!("?{index}"))
        .collect::<Vec<_>>()
        .join(", ")
}

pub(super) fn non_empty_trimmed(value: Option<&str>) -> Option<&str> {
    value.map(str::trim).filter(|value| !value.is_empty())
}

pub(super) fn push_unique(values: &mut Vec<String>, value: String) {
    if !values.iter().any(|existing| existing == &value) {
        values.push(value);
    }
}

pub(super) fn push_unique_i64(values: &mut Vec<i64>, value: i64) {
    if !values.contains(&value) {
        values.push(value);
    }
}