use crate::{Deserialize, Deserializer, Vec, H256};

pub fn de_string_to_bytes<'de, D>(de: D) -> Result<Option<Vec<u8>>, D::Error>
where
    D: Deserializer<'de>,
{
    let s: &str = Deserialize::deserialize(de)?;
    Ok(Some(s.as_bytes().to_vec()))
}

pub fn de_string_to_block_number<'de, D>(de: D) -> Result<Option<u64>, D::Error>
where
    D: Deserializer<'de>,
{
    let s: &str = Deserialize::deserialize(de)?;
    let s = if s.starts_with("0x") { &s[2..] } else { &s };
    Ok(u64::from_str_radix(s, 16).ok())
}

pub fn de_string_to_block_number_pure<'de, D>(de: D) -> Result<u64, D::Error>
where
    D: Deserializer<'de>,
{
    let s: &str = Deserialize::deserialize(de)?;
    let s = if s.starts_with("0x") { &s[2..] } else { &s };
    Ok(u64::from_str_radix(s, 16).unwrap_or_default())
}

pub fn de_string_to_h256<'de, D>(de: D) -> Result<Option<H256>, D::Error>
where
    D: Deserializer<'de>,
{
    let s: &str = Deserialize::deserialize(de)?;
    let start_index = if s.starts_with("0x") { 2 } else { 0 };
    let h256: Vec<_> = (start_index..s.len())
        .step_by(2)
        .map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
        .collect();
    Ok(Some(H256::from_slice(&h256)))
}

pub fn de_string_to_vec_of_bytes<'de, D>(de: D) -> Result<Vec<Vec<u8>>, D::Error>
where
    D: Deserializer<'de>,
{
    let strings: Vec<&str> = Deserialize::deserialize(de)?;
    Ok(strings
        .iter()
        .map(|s| {
            let start_index = if s.starts_with("0x") { 2 } else { 0 };
            (start_index..s.len())
                .step_by(2)
                .map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
                .collect::<Vec<u8>>()
        })
        .collect::<Vec<Vec<u8>>>())
}
