use std::{fmt::Debug, ops::RangeBounds};
use crate::{rule::string::StringRule, Rule, Value};
use super::Message;
#[derive(Clone)]
pub struct Length<T>(pub T);
impl<T: Debug> Debug for Length<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Length").field(&self.0).finish()
}
}
crate::__impl_copy!(Length);
crate::__impl_deref!(Length);
const NAME: &str = "length";
impl<T> Length<T> {
fn message_in(&self) -> Message {
Message::new(super::MessageKind::Length)
}
pub const fn as_ref(&self) -> Length<&T> {
let Length(ref t) = self;
Length(t)
}
pub fn as_mut(&mut self) -> Length<&mut T> {
let Length(ref mut t) = self;
Length(t)
}
}
impl<T> Rule for Length<T>
where
T: RangeBounds<usize> + Clone,
{
type Message = Message;
const NAME: &'static str = NAME;
fn message(&self) -> Self::Message {
self.message_in()
}
fn call(&mut self, data: &mut Value) -> bool {
match data {
Value::String(str) => self.0.contains(&str.len()),
Value::Array(arr) => self.0.contains(&arr.len()),
Value::Map(map) => self.0.contains(&map.len()),
_ => false,
}
}
}
impl<T> StringRule for Length<T>
where
T: RangeBounds<usize> + Clone,
{
type Message = Message;
const NAME: &'static str = NAME;
fn message(&self) -> Self::Message {
self.message_in()
}
fn call(&mut self, data: &mut String) -> bool {
self.0.contains(&data.len())
}
}
#[derive(Debug, Clone, Copy)]
pub struct Num(usize);
impl Length<Num> {
pub const fn eq(length: usize) -> Self {
Self(Num(length))
}
}
impl PartialEq<usize> for Num {
fn eq(&self, other: &usize) -> bool {
self.0 == *other
}
}
impl Rule for Length<Num> {
type Message = Message;
const NAME: &'static str = NAME;
fn message(&self) -> Self::Message {
self.message_in()
}
fn call(&mut self, data: &mut Value) -> bool {
match data {
Value::String(str) => self.0 == str.len(),
Value::Array(arr) => self.0 == arr.len(),
Value::Map(map) => self.0 == map.len(),
_ => false,
}
}
}
impl StringRule for Length<Num> {
type Message = Message;
const NAME: &'static str = NAME;
fn message(&self) -> Self::Message {
self.message_in()
}
fn call(&mut self, data: &mut String) -> bool {
self.0 == data.len()
}
}
impl<T> Length<&T> {
pub const fn copied(self) -> Length<T>
where
T: Copy,
{
Length(*self.0)
}
pub fn cloned(self) -> Length<T>
where
T: Clone,
{
Length(self.0.clone())
}
}
impl<T> Length<&mut T> {
pub fn copied(self) -> Length<T>
where
T: Copy,
{
Length(*self.0)
}
pub fn cloned(self) -> Length<T>
where
T: Clone,
{
Length(self.0.clone())
}
}
impl<T: PartialEq> PartialEq for Length<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}