//! Types for element and pipeline IO

use std::{borrow::ToOwned, convert::Into};

use super::raw::Data;

/// Newtype struct with borrowed types for pipeline/element inputs, so that doesn't force a move or clone
#[derive(PartialEq, Eq, Debug)]
pub struct Inputs<'a>(pub Vec<&'a Data>);

impl<'a> From<Vec<&'a Data>> for Inputs<'a> {
    fn from(value: Vec<&'a Data>) -> Self {
        Self(value)
    }
}

impl<'a, T: Into<&'a Data>> From<T> for Inputs<'a> {
    fn from(value: T) -> Self {
        Self(vec![value.into()])
    }
}

impl<'a> From<&'a Outputs> for Inputs<'a> {
    fn from(value: &'a Outputs) -> Self {
        Self(value.0.iter().map(Into::into).collect())
    }
}

/// Used for pipeline/element outputs
#[derive(PartialEq, Eq, Debug)]
pub struct Outputs(pub Vec<Data>);

impl Outputs {
    /// consume self and return inner value(s)
    pub fn into_inner(self) -> Vec<Data> {
        self.0
    }
}
impl From<Vec<Data>> for Outputs {
    fn from(value: Vec<Data>) -> Self {
        Self(value)
    }
}
impl<T: Into<Data>> From<T> for Outputs {
    fn from(value: T) -> Self {
        Self(vec![value.into()])
    }
}
impl From<Inputs<'_>> for Outputs {
    fn from(value: Inputs) -> Self {
        Self(value.0.into_iter().map(ToOwned::to_owned).collect())
    }
}
