1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use encodings::FromHex;
use extended_primitives::Buffer;
use serde::de::{self, SeqAccess, Visitor};
use serde::{Deserialize, Deserializer};
use serde_tuple::*;
use std::fmt;

// #[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Serialize_tuple, Clone, Debug, Default)]
pub struct Submit {
    pub username: String,
    pub job_id: String,
    pub nonce_2: Buffer,
    pub timestamp: u64,
    pub nonce: u32,
    pub mask: Option<Buffer>,
}

impl<'de> Deserialize<'de> for Submit {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct SubmitVisitor;
        use serde::de::Error;

        #[derive(Deserialize)]
        #[serde(untagged)]
        enum StringOrInt {
            String(String),
            Int(u64),
        }

        // match StringOrInt::deserialize(deserializer)? {
        //     StringOrInt::String(s) => s.parse().map_err(de::Error::custom),
        //     StringOrInt::Int(i) => Ok(i),
        // }

        impl<'de> Visitor<'de> for SubmitVisitor {
            type Value = Submit;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("struct Duration")
            }

            fn visit_seq<V>(self, mut seq: V) -> Result<Submit, V::Error>
            where
                V: SeqAccess<'de>,
            {
                let username = seq
                    .next_element()?
                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
                let job_id = seq
                    .next_element()?
                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
                let nonce_2 = seq
                    .next_element()?
                    .ok_or_else(|| de::Error::invalid_length(2, &self))?;
                let timestamp: StringOrInt = seq
                    .next_element()?
                    .ok_or_else(|| de::Error::invalid_length(3, &self))?;
                let nonce: StringOrInt = seq
                    .next_element()?
                    .ok_or_else(|| de::Error::invalid_length(4, &self))?;

                let mask = seq.next_element()?;

                if mask.is_some() {
                    let real_timestamp = match timestamp {
                        StringOrInt::String(hex) => {
                            let bytes = Vec::from_hex(hex).map_err(Error::custom)?;

                            let mut byte_array = [0u8; 4];
                            byte_array.copy_from_slice(&bytes);

                            u32::from_be_bytes(byte_array) as u64
                        }
                        StringOrInt::Int(raw) => raw,
                    };

                    let real_nonce = match nonce {
                        StringOrInt::String(hex) => {
                            let bytes = Vec::from_hex(hex).map_err(Error::custom)?;

                            let mut byte_array = [0u8; 4];
                            byte_array.copy_from_slice(&bytes);

                            u32::from_be_bytes(byte_array)
                        }
                        StringOrInt::Int(raw) => raw as u32,
                    };

                    // let bytes = Vec::from_hex(timestamp).map_err(Error::custom)?;

                    // let mut byte_array = [0u8; 4];
                    // byte_array.copy_from_slice(&bytes);

                    // let timestamp = u32::from_be_bytes(byte_array) as u64;

                    // let bytes = Vec::from_hex(nonce).map_err(Error::custom)?;

                    // let mut byte_array = [0u8; 4];
                    // byte_array.copy_from_slice(&bytes);

                    // let nonce = u32::from_be_bytes(byte_array);

                    Ok(Submit {
                        username,
                        job_id,
                        nonce_2,
                        timestamp: real_timestamp,
                        nonce: real_nonce,
                        mask,
                    })
                } else {
                    let real_timestamp = match timestamp {
                        StringOrInt::String(raw_time) => raw_time.parse().map_err(Error::custom)?,
                        StringOrInt::Int(raw) => raw,
                    };

                    let real_nonce = match nonce {
                        StringOrInt::String(raw_nonce) => {
                            raw_nonce.parse().map_err(Error::custom)?
                        }
                        StringOrInt::Int(raw) => raw as u32,
                    };

                    Ok(Submit {
                        username,
                        job_id,
                        nonce_2,
                        timestamp: real_timestamp,
                        nonce: real_nonce,
                        mask,
                    })
                }
            }
        }

        deserializer.deserialize_seq(SubmitVisitor)
    }
}