
use crate::data::error::{EcState, LinkState, RedundancyState, CiA402State, CiA402Mode};
use crate::slave::core::Slave;
use crate::utils::ffi::SlaveIdentity;

impl From<&Slave> for SlaveIdentity {

    fn from(s: &Slave) -> Self {
        SlaveIdentity {
            vendor_id: s.vendor_id(),
            product_code: s.product_id(),
            revision_no: s.rev_id(),
            serial_no: 0,
        }
    }
}

impl From<Slave> for SlaveIdentity {
    fn from(s: Slave) -> Self {
        (&s).into()
    }
}

impl From<u8> for EcState {

    fn from(v: u8) -> Self {
        EcState::from_raw(v).unwrap_or(EcState::None)
    }
}

impl From<EcState> for u8 {

    fn from(s: EcState) -> u8 {
        s as u8
    }
}

impl From<EcState> for i32 {

    fn from(s: EcState) -> i32 {
        (s as u8) as i32
    }
}

impl From<u8> for LinkState {
    fn from(v: u8) -> Self {
        LinkState::from_raw(v)
    }
}

impl From<LinkState> for u8 {
    fn from(s: LinkState) -> u8 {
        s as u8
    }
}

impl From<i32> for RedundancyState {
    fn from(v: i32) -> Self {
        RedundancyState::from_raw(v)
    }
}

impl From<RedundancyState> for i32 {
    fn from(s: RedundancyState) -> i32 {
        s as i32
    }
}

impl From<i32> for CiA402State {
    fn from(v: i32) -> Self {
        CiA402State::from_raw(v)
    }
}

impl From<CiA402State> for i32 {
    fn from(s: CiA402State) -> i32 {
        s as i32
    }
}

impl From<CiA402Mode> for i8 {
    fn from(m: CiA402Mode) -> i8 {
        m as i8
    }
}

impl From<CiA402Mode> for i32 {
    fn from(m: CiA402Mode) -> i32 {
        (m as i8) as i32
    }
}

impl From<EcState> for &'static str {
    fn from(s: EcState) -> &'static str {
        match s {
            EcState::None => "None",
            EcState::Init => "Init",
            EcState::PreOp => "PreOp",
            EcState::Boot => "Boot",
            EcState::SafeOp => "SafeOp",
            EcState::Operational => "OP",
        }
    }
}

impl From<LinkState> for &'static str {
    fn from(s: LinkState) -> &'static str {
        match s {
            LinkState::Disconnected => "Disconnected",
            LinkState::Connected => "Connected",
            LinkState::Redundancy => "Redundancy",
            LinkState::PrimaryOnly => "PrimaryOnly",
            LinkState::SecondaryOnly => "SecondaryOnly",
        }
    }
}

impl From<RedundancyState> for &'static str {
    fn from(s: RedundancyState) -> &'static str {
        match s {
            RedundancyState::None => "None",
            RedundancyState::Primary => "PrimaryOnly",
            RedundancyState::Secondary => "SecondaryOnly",
            RedundancyState::Both => "Both",
        }
    }
}
