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

//! Implements `DirectMatch` for `StringCriterium`.

use crate::direct_match::DirectMatchResult;
use crate::string::StringCriterium;
use crate::DirectMatch;

impl DirectMatch<str> for StringCriterium {
	type Output = bool;

	fn criterium_match(&self, data: &str) -> bool {
		match self {
			Self::Equals(my) => data == my,
			Self::HasPrefix(my) => data.starts_with(my),
			Self::HasSuffix(my) => data.ends_with(my),
			Self::Contains(my) => data.contains(my),
			Self::Length(c) => c.criterium_match(&data.chars().count()),
			Self::IsNone => false,
		}
	}
}

impl DirectMatch<String> for StringCriterium {
	type Output = bool;

	fn criterium_match(&self, data: &String) -> bool {
		self.criterium_match(data.as_str())
	}
}

impl<V> DirectMatch<Option<&V>> for StringCriterium
where
	StringCriterium: DirectMatch<V>,
	V: ?Sized,
{
	type Output = <StringCriterium as DirectMatch<V>>::Output;

	fn criterium_match(&self, data: &Option<&V>) -> Self::Output {
		if let Some(n) = *data {
			return self.criterium_match(n);
		} else {
			Self::Output::new(matches!(self, Self::IsNone))
		}
	}
}
