mod string_pattern;

pub use string_pattern::StringPattern;

use crate::assertions::string::*;
use crate::core::assert::ChainableAssert;
use std::fmt::Debug;

/// Extension for Should<AsRef<str>>. See the method documentation.
pub trait ShouldString<S: Debug>
where
    S: AsRef<str>,
{
    /// Checks that a string contains a pattern.
    ///
    /// # Example
    ///
    /// ```rust
    /// # use fluid::prelude::*;
    /// "Hello".should().contain('l');
    /// "Hello".should().contain("ll");
    /// "Hello".should().contain(['a', 'e', 'i']);
    /// ```
    ///
    /// ```rust
    /// # use fluid::prelude::*;
    /// "Hello".should().not().contain(|c: char| c.is_numeric());
    /// ```
    fn contain<P>(self, right: P) -> ChainableAssert<ContainString<S, P>>
    where
        P: StringPattern;

    /// Checks that a string begins with a pattern.
    ///
    /// # Example
    ///
    /// ```rust
    /// # use fluid::prelude::*;
    /// "Hello".should().start_with("He");
    /// ```
    fn start_with<P>(self, right: P) -> ChainableAssert<StartWithString<S, P>>
    where
        P: StringPattern;

    /// Checks that a string ends with a pattern.
    ///
    /// # Example
    ///
    /// ```rust
    /// # use fluid::prelude::*;
    /// "Hello".should().end_with('o');
    /// ```
    fn end_with<P>(self, right: P) -> ChainableAssert<EndWithString<S, P>>
    where
        P: StringPattern;

    /// Checks that a string is empty.
    ///
    /// # Example
    ///
    /// ```rust
    /// # use fluid::prelude::*;
    /// "Hello".should().not().be_empty();
    /// ```
    fn be_empty(self) -> ChainableAssert<BeEmptyString<S>>;
}
