// SPDX-FileCopyrightText: 2025 Slatian
//
// SPDX-License-Identifier: LGPL-3.0-only

//! For matching one to many relationships

use crate::chain::CriteriumChain;
use crate::number::NumberCriterium;

pub mod direct_match;

#[cfg(feature = "rusqlite")]
pub mod rusqlite;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// The tag criterium is for whenever there is a <i>one to many</i> relationship.
///
/// It joins in the tag objects and
/// counts how many of them match a given criterium chain.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
pub enum TagCriterium<T> {
	/// Matches if there are any (greater_equal 1) tag matches.
	Has(CriteriumChain<T>),
	/// Matches if there are no tag matches found.
	HasNot(CriteriumChain<T>),
	/// Matches the NumberCriterium `n` against the number of found tag matches.
	///
	/// This will short circuit on unknown values if possible
	HasNOf {
		/// The criterium for the number of expected matches
		n: NumberCriterium<i64>,

		/// The chain that has to match.
		#[cfg_attr(feature = "serde", serde(rename = "where"))]
		chain: CriteriumChain<T>,
	},
}
