use crate::core::display::PrintDebug;
use crate::core::information::{FromMacro, Information};
use crate::core::should::{Should, ShouldImpl};
use std::fmt::Debug;

#[derive(Debug)]
#[must_use]
/// Structure to initiate the `Should` structure , when the `should` method is called.
/// It is used by the macros.
pub struct LeftElement<L: Debug> {
    left: L,
    from_macro: FromMacro,
}

impl<L: Debug> LeftElement<L> {
    /// Creates a new `LeftElement`. Not intended to be used directly,
    /// but through the custom attributes or the `fact_` macro.
    pub fn new(
        left: L,
        stringified: &'static str,
        location: &'static str,
        case: Option<&'static str>,
    ) -> Self {
        let from_macro = FromMacro {
            stringified,
            location,
            case,
        };

        LeftElement { left, from_macro }
    }

    /// Initiates a new assertion.
    pub fn should(self) -> Should<L> {
        let LeftElement { left, from_macro } = self;
        let left_dbg = left.dbg().to_string();
        let info = Information::new(Some(from_macro), left_dbg);

        Should(ShouldImpl {
            truthness: true,
            left: Some(left),
            info,
        })
    }
}
