//! Operation on String/text data
use crate::experimental::trait_based::{
    data::{
        io::{Inputs, Outputs},
        raw::Data,
    },
    element::{ElementSignature, PipelineElement},
};

/// Concatenate the inputs
pub struct Concatenate(pub String);
impl PipelineElement for Concatenate {
    fn runner(&self) -> fn(&Inputs) -> Outputs {
        |input| {
            let [Data::String(s0), Data::String(s1), ..] = input.0[..] else {
                panic!("Invalid data passed")
            };
            format!("{s0}{s1}").into()
        }
    }

    fn signature(&self) -> ElementSignature {
        signature!(String, String => String)
    }
}

/// Turn input text to uppercase
pub struct Upper;
impl PipelineElement for Upper {
    fn runner(&self) -> fn(&Inputs) -> Outputs {
        |input| {
            let [Data::String(s), ..] = input.0[..] else {
                panic!("Invalid data passed")
            };
            s.to_uppercase().into()
        }
    }

    fn signature(&self) -> ElementSignature {
        signature!(String => String)
    }
}

/// Turn input text to lowercase
pub struct Lower;
impl PipelineElement for Lower {
    fn runner(&self) -> fn(&Inputs) -> Outputs {
        |input| {
            let [Data::String(s), ..] = input.0[..] else {
                panic!("Invalid data passed")
            };
            s.to_lowercase().into()
        }
    }

    fn signature(&self) -> ElementSignature {
        signature!(String => String)
    }
}
