implement Network send

This commit is contained in:
CodeSteak 2019-04-24 18:14:11 +02:00
parent 1ae8bed86b
commit aa55b5948e
3 changed files with 101 additions and 4 deletions

View File

@ -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

View File

@ -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!(),
}

View File

@ -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]));
}
}