ax_aql 0.1.0

AQL parsing and rendering for ax
Documentation
#![allow(dead_code)]
use std::{convert::TryFrom, ops::Deref, sync::Arc};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct NonEmptyVec<T>(Arc<[T]>);

impl<T> NonEmptyVec<T> {
    pub fn map<U>(&self, f: impl FnMut(&T) -> U) -> NonEmptyVec<U> {
        NonEmptyVec(self.iter().map(f).collect())
    }
}

#[derive(Debug, Clone)]
pub struct NoElements;
impl std::error::Error for NoElements {}
impl std::fmt::Display for NoElements {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "cannot construct NonEmptyVec without elements")
    }
}

impl<T> TryFrom<Vec<T>> for NonEmptyVec<T> {
    type Error = NoElements;

    fn try_from(value: Vec<T>) -> Result<Self, Self::Error> {
        if value.is_empty() {
            Err(NoElements)
        } else {
            Ok(Self(value.into()))
        }
    }
}

impl<T> Deref for NonEmptyVec<T> {
    type Target = [T];

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

#[cfg(test)]
impl<T: quickcheck::Arbitrary + Clone + 'static> quickcheck::Arbitrary for NonEmptyVec<T> {
    fn arbitrary(g: &mut quickcheck::Gen) -> Self {
        let mut v = Vec::<T>::arbitrary(g);
        loop {
            if !v.is_empty() {
                break;
            }
            v = Vec::<T>::arbitrary(g);
        }
        Self(v.into())
    }
    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
        Box::new(
            self.0
                .to_vec()
                .shrink()
                .filter(|v| !v.is_empty())
                .map(|v| Self(v.into())),
        )
    }
}

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct NonEmptyString(String);

#[derive(Debug, Clone)]
pub struct NoChars;
impl std::error::Error for NoChars {}
impl std::fmt::Display for NoChars {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "cannot construct NonEmptyString without characters")
    }
}

impl TryFrom<String> for NonEmptyString {
    type Error = NoElements;

    fn try_from(value: String) -> Result<Self, Self::Error> {
        if value.is_empty() {
            Err(NoElements)
        } else {
            Ok(Self(value))
        }
    }
}

impl TryFrom<&str> for NonEmptyString {
    type Error = NoElements;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        if value.is_empty() {
            Err(NoElements)
        } else {
            Ok(Self(value.to_owned()))
        }
    }
}

impl Deref for NonEmptyString {
    type Target = str;

    fn deref(&self) -> &Self::Target {
        self.0.as_str()
    }
}

impl NonEmptyString {
    pub fn into_inner(self) -> String {
        self.0
    }
}

impl std::fmt::Display for NonEmptyString {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0)
    }
}

#[cfg(test)]
impl quickcheck::Arbitrary for NonEmptyString {
    fn arbitrary(g: &mut quickcheck::Gen) -> Self {
        let mut v = String::arbitrary(g);
        loop {
            if !v.is_empty() {
                break;
            }
            v = String::arbitrary(g);
        }
        Self(v)
    }
    fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
        Box::new(self.0.shrink().filter(|v| !v.is_empty()).map(Self))
    }
}