implement Network send
This commit is contained in:
		@ -1,7 +1,7 @@
 | 
			
		||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
 | 
			
		||||
pub struct Sha256(#[serde(serialize_with = "as_hex", deserialize_with = "from_hex")] [u8; 32]);
 | 
			
		||||
pub struct Sha256(#[serde(serialize_with = "as_hex", deserialize_with = "from_hex")] pub [u8; 32]);
 | 
			
		||||
 | 
			
		||||
fn as_hex<S>(hash: &[u8; 32], serializer: S) -> Result<S::Ok, S::Error>
 | 
			
		||||
where
 | 
			
		||||
 | 
			
		||||
@ -46,13 +46,28 @@ where
 | 
			
		||||
                // Just clone the connection.
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Package::Binary(_) => {
 | 
			
		||||
                connection.send(&Package::Error(400, "Unexpected Binary".to_string()))?;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Package::JsonTrue | Package::JsonFalse | Package::JsonNull => {
 | 
			
		||||
                connection.send(&Package::Error(
 | 
			
		||||
                    400,
 | 
			
		||||
                    "Unexpected true, false or null. ".to_string(),
 | 
			
		||||
                ))?;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Package::Json(Command::Ping {}) => {
 | 
			
		||||
                connection.send(&Package::Json(Command::Pong {}))?;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Package::Json(Command::Pong {}) => {
 | 
			
		||||
                // Ignore
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // TODO: lots
 | 
			
		||||
            _ => unimplemented!(),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -69,6 +69,12 @@ impl<R: Read + Sized, W: Write + Sized> Connection<R, W> {
 | 
			
		||||
        Connection { reader, writer }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[cfg(test)]
 | 
			
		||||
    pub fn destruct(self) -> (R, W) {
 | 
			
		||||
        let Connection { reader, writer } = self;
 | 
			
		||||
        (reader, writer)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn receive(&mut self) -> Result<Package> {
 | 
			
		||||
        let mut payload_type_buffer = [0u8; 1];
 | 
			
		||||
        let mut reserved_buffer = [0u8; 3];
 | 
			
		||||
@ -172,7 +178,52 @@ impl<R: Read + Sized, W: Write + Sized> Connection<R, W> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn send(&mut self, pkg: &Package) -> Result<()> {
 | 
			
		||||
        unimplemented!()
 | 
			
		||||
        match pkg {
 | 
			
		||||
            Package::JsonNull => self.send_json(&Option::<bool>::None),
 | 
			
		||||
            Package::JsonTrue => self.send_json(&true),
 | 
			
		||||
            Package::JsonFalse => self.send_json(&false),
 | 
			
		||||
            Package::Json(cmd) => self.send_json(cmd),
 | 
			
		||||
 | 
			
		||||
            Package::Binary(bin) => self.send_binary(bin),
 | 
			
		||||
            Package::Error(code, msg) => self.send_error(*code, msg),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn send_json<J: 'static + Serialize + Sized>(&mut self, msg: &J) -> Result<()> {
 | 
			
		||||
        let w = &mut self.writer;
 | 
			
		||||
 | 
			
		||||
        let payload = serde_json::to_vec(msg).unwrap();
 | 
			
		||||
 | 
			
		||||
        w.write_all(&[PACKAGE_TYPE_JSON, 42, 42, 42])?;
 | 
			
		||||
        w.write_all(&(payload.len() as u32).to_be_bytes())?;
 | 
			
		||||
 | 
			
		||||
        w.write_all(&payload[..])?;
 | 
			
		||||
 | 
			
		||||
        w.flush()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn send_binary(&mut self, payload: &[u8]) -> Result<()> {
 | 
			
		||||
        let w = &mut self.writer;
 | 
			
		||||
 | 
			
		||||
        w.write_all(&[PACKAGE_TYPE_BIN, 42, 42, 42])?;
 | 
			
		||||
        w.write_all(&(payload.len() as u32).to_be_bytes())?;
 | 
			
		||||
 | 
			
		||||
        w.write_all(payload)?;
 | 
			
		||||
 | 
			
		||||
        w.flush()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn send_error(&mut self, code: u16, msg: &str) -> Result<()> {
 | 
			
		||||
        let w = &mut self.writer;
 | 
			
		||||
 | 
			
		||||
        let payload = format!("{:03} {}", code, msg).into_bytes();
 | 
			
		||||
 | 
			
		||||
        w.write_all(&[PACKAGE_TYPE_ERROR, 42, 42, 42])?;
 | 
			
		||||
        w.write_all(&(payload.len() as u32).to_be_bytes())?;
 | 
			
		||||
 | 
			
		||||
        w.write_all(&payload[..])?;
 | 
			
		||||
 | 
			
		||||
        w.flush()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -180,6 +231,26 @@ impl<R: Read + Sized, W: Write + Sized> Connection<R, W> {
 | 
			
		||||
mod test {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    use crate::model::*;
 | 
			
		||||
 | 
			
		||||
    // Utility fn
 | 
			
		||||
 | 
			
		||||
    fn test_read_back(pkg: &Package) {
 | 
			
		||||
        let dummy_read_data = [255u8];
 | 
			
		||||
 | 
			
		||||
        // generate write
 | 
			
		||||
        let mut c = Connection::new(&dummy_read_data[..], Vec::new());
 | 
			
		||||
        c.send(&pkg).unwrap();
 | 
			
		||||
 | 
			
		||||
        let (_, written) = c.destruct();
 | 
			
		||||
 | 
			
		||||
        // read back in
 | 
			
		||||
        let mut c = Connection::new(&written[..], Vec::new() /*dummy*/);
 | 
			
		||||
        let read_back_pkg = c.receive().unwrap();
 | 
			
		||||
 | 
			
		||||
        assert_eq!(&read_back_pkg, pkg)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn read_error_good() {
 | 
			
		||||
        let mut read_data = Vec::new();
 | 
			
		||||
@ -236,8 +307,6 @@ mod test {
 | 
			
		||||
    // we don't test the actual json parsing here,
 | 
			
		||||
    // since serde_json is well tested.
 | 
			
		||||
 | 
			
		||||
    // AndTesting the declaration seams not worth the effort.
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn read_json_good() {
 | 
			
		||||
        let mut read_data = Vec::new();
 | 
			
		||||
@ -301,4 +370,17 @@ mod test {
 | 
			
		||||
 | 
			
		||||
        assert_eq!(c.receive().is_err(), true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn writes() {
 | 
			
		||||
        test_read_back(&Package::JsonNull);
 | 
			
		||||
        test_read_back(&Package::JsonFalse);
 | 
			
		||||
        test_read_back(&Package::JsonTrue);
 | 
			
		||||
 | 
			
		||||
        test_read_back(&Package::Json(Command::Pong {}));
 | 
			
		||||
 | 
			
		||||
        test_read_back(&Package::Error(500, "I bims 1 Error".to_string()));
 | 
			
		||||
 | 
			
		||||
        test_read_back(&Package::Binary(vec![42u8; 50000]));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user