use crate::{Result, SemanticError};
use weavatrix_graph::Confidence;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub enum SelectionMode {
#[default]
Mutual,
Union,
Directed,
}
impl SelectionMode {
pub(crate) const fn as_str(self) -> &'static str {
match self {
Self::Mutual => "mutual",
Self::Union => "union",
Self::Directed => "directed",
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct LinkConfig {
model: String,
min_similarity: f64,
top_k: usize,
selection: SelectionMode,
confidence: Confidence,
max_vectors: usize,
}
impl LinkConfig {
#[must_use]
pub fn new(model: impl Into<String>, min_similarity: f64, top_k: usize) -> Self {
Self {
model: model.into(),
min_similarity,
top_k,
selection: SelectionMode::Mutual,
confidence: Confidence::Low,
max_vectors: usize::MAX,
}
}
#[must_use]
pub const fn with_selection(mut self, selection: SelectionMode) -> Self {
self.selection = selection;
self
}
#[must_use]
pub const fn with_confidence(mut self, confidence: Confidence) -> Self {
self.confidence = confidence;
self
}
#[must_use]
pub const fn with_max_vectors(mut self, max_vectors: usize) -> Self {
self.max_vectors = max_vectors;
self
}
#[must_use]
pub fn model(&self) -> &str {
&self.model
}
#[must_use]
pub const fn min_similarity(&self) -> f64 {
self.min_similarity
}
#[must_use]
pub const fn top_k(&self) -> usize {
self.top_k
}
#[must_use]
pub const fn selection(&self) -> SelectionMode {
self.selection
}
#[must_use]
pub const fn confidence(&self) -> Confidence {
self.confidence
}
#[must_use]
pub const fn max_vectors(&self) -> usize {
self.max_vectors
}
pub(crate) fn validate(&self) -> Result<()> {
if self.model.is_empty() {
return Err(SemanticError::EmptyModel);
}
if self.model.trim() != self.model {
return Err(SemanticError::ModelHasSurroundingWhitespace);
}
if !self.min_similarity.is_finite() || !(0.0..=1.0).contains(&self.min_similarity) {
return Err(SemanticError::InvalidSimilarityThreshold);
}
if self.top_k == 0 {
return Err(SemanticError::ZeroTopK);
}
if self.max_vectors == 0 {
return Err(SemanticError::ZeroMaxVectors);
}
Ok(())
}
}