//! Operations on numeric data
use core::panic;
use std::any::TypeId;

use crate::experimental::trait_based::{
    data::{
        io::{Inputs, Outputs},
        raw::Data,
    },
    element::{ElementSignature, PipelineElement},
};

/// Addition
pub struct Add(pub i32);
impl PipelineElement for Add {
    fn runner(&self) -> fn(&Inputs) -> Outputs {
        |input| {
            let [Data::Int(i0), Data::Int(i1), ..] = input.0[..] else {
                panic!("Invalid data passed")
            };
            (i0 + i1).into()
        }
    }

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

/// Subtraction
pub struct Subtract(pub i32);
impl PipelineElement for Subtract {
    fn runner(&self) -> fn(&Inputs) -> Outputs {
        |input| {
            let [Data::Int(i0), Data::Int(i1), ..] = input.0[..] else {
                panic!("Invalid data passed")
            };
            (i0 + i1).into()
        }
    }

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

/// Turn input to string
pub struct Stringify;
impl PipelineElement for Stringify {
    fn runner(&self) -> fn(&Inputs) -> Outputs {
        |input| {
            let [Data::Int(int), ..] = input.0[..] else {
                panic!("Invalid data passed")
            };
            int.to_string().into()
        }
    }

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