From 68428fbd84976c689364ec57e552f0f3603a4794 Mon Sep 17 00:00:00 2001 From: Alex Helfet Date: Sun, 24 Dec 2017 19:45:33 +0000 Subject: [PATCH] Interface, dependencies, builds for typed sub-module. --- Cargo.toml | 11 +++++- bin/build_local | 6 ++-- bin/travis/script | 1 + src/lib.rs | 13 +++++-- src/typed.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 src/typed.rs diff --git a/Cargo.toml b/Cargo.toml index 5c15588..cf068f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,12 +16,21 @@ branch = "master" [dependencies] cobs = "^0.1.3" ref_slice = "^1.1.1" +serde = { version = "^1.0", optional = true } +ssmarshal = { version = "^1.0", optional = true } + +[dev-dependencies] +serde_derive = "^1.0" [features] -default = ["use_std"] +default = ["use_std", "typed"] # Enable to print all data to stdout for testing. trace = [] # Use standard library. Enabled by default, disable for no_std. use_std = [] + +# Enables the `typed` sub-module for sending and receiving +# structs serialized with serde. +typed = ["serde", "ssmarshal"] diff --git a/bin/build_local b/bin/build_local index a5701ab..441f3a9 100755 --- a/bin/build_local +++ b/bin/build_local @@ -8,11 +8,13 @@ rustup toolchain update beta; rustup toolchain update nightly; cargo +stable build --verbose; -cargo +beta build --verbose; +cargo +stable build --verbose --no-default-features; +cargo +beta build --verbose; +cargo +beta build --verbose --no-default-features; cargo +nightly test --verbose; cargo +nightly test --verbose --no-default-features; cargo +stable doc --verbose; -cargo +beta doc --verbose; +cargo +beta doc --verbose; cargo +nightly doc --verbose; diff --git a/bin/travis/script b/bin/travis/script index d07daa4..5940598 100755 --- a/bin/travis/script +++ b/bin/travis/script @@ -5,6 +5,7 @@ echo "TRAVIS_RUST_VERSION: '${TRAVIS_RUST_VERSION}'" set -x cargo build --verbose; +cargo build --verbose --no-default-features; if [[ "${TRAVIS_RUST_VERSION}" == "nightly" ]]; then cargo test --verbose; diff --git a/src/lib.rs b/src/lib.rs index 97d65f5..fc525fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,9 @@ //! //! `trace`: Enable to print all data to stdout for testing. //! +//! `typed`: Enables the [`typed`](typed/index.html) sub-module for sending and +//! receiving structs serialized with serde. +//! //! ## API //! //! Payload data and encoded frame data have separate types to avoid @@ -65,7 +68,7 @@ //! See the `decode_*` and `encode_*` functions for simple uses with //! various input and output types. //! -//! Note that data (`type`ed as `Payload` or `Encoded`) may be +//! Note that data typed as `Payload` or `Encoded` may be //! efficiently passed as a function argument by reference, but is //! returned using an opaque struct (`BoxPayload`, `BoxEncoded`) //! containing a heap-allocated value instead. Consequently `encode_*` @@ -82,8 +85,11 @@ #![cfg_attr(not(feature = "use_std"), no_std)] extern crate cobs; - extern crate ref_slice; +#[cfg(feature = "typed")] +extern crate serde; +#[cfg(feature = "typed")] +extern crate ssmarshal; #[cfg(feature = "use_std")] use ref_slice::ref_slice_mut; @@ -101,7 +107,8 @@ pub mod error; #[allow(unused_imports)] use error::{Error, Result}; - +#[cfg(feature = "typed")] +pub mod typed; /// Arbitrary user data. pub type Payload = [u8]; diff --git a/src/typed.rs b/src/typed.rs new file mode 100644 index 0000000..1f15dab --- /dev/null +++ b/src/typed.rs @@ -0,0 +1,89 @@ +//! Sending and receiving structs serialized with serde. + +use error::{Result}; +use serde::Serialize; +use serde::de::DeserializeOwned; +// use ssmarshal; +use std::io::{Read, Write}; +use std::marker::PhantomData; + + +/// Sends encoded structs of type `T` over an inner `io::Write` instance. +pub struct Sender { + w: W, + _t: PhantomData, +} + +impl Sender { + /// Construct a `Sender` that sends encoded structs over the supplied + /// `io::Write`. + pub fn new(w: W) -> Sender { + Sender:: { + w: w, + _t: PhantomData::default(), + } + } + + /// Consume this `Sender` and return the inner `io::Write`. + pub fn into_inner(self) -> W { + self.w + } + + /// Flush all buffered data. Includes calling `flush` on the inner + /// writer. + pub fn flush(&mut self) -> Result<()> { + Ok(self.w.flush()?) + } + + /// Queue the supplied payload for transmission. + /// + /// This `Sender` may buffer the data indefinitely, as may the + /// inner writer. To ensure all buffered data has been + /// transmitted call [`flush`](#method.flush). + /// + /// See also: [`send`](#method.send) + pub fn queue(&mut self, _v: &T) -> Result { + unimplemented!(); + } + + /// Encode the supplied payload as a frame, write it to the + /// inner writer, then flush. + /// + /// Ensures the data has been transmitted before returning to the + /// caller. + /// + /// See also: [`queue`](#method.queue) + pub fn send(&mut self, v: &T) -> Result { + let len = self.queue(v)?; + self.flush()?; + Ok(len) + } +} + +/// Receives encoded structs of type `T` from an inner `io::Read` instance. +pub struct Receiver { + r: R, + _t: PhantomData, +} + +impl Receiver { + /// Construct a `Receiver` that receives encoded structs from the supplied + /// `io::Read`. + pub fn new(r: R) -> Receiver { + Receiver:: { + r: r, + _t: PhantomData::default(), + } + } + + /// Consume this `Receiver` and return the inner `io::Read`. + pub fn into_inner(self) -> R { + self.r + } + + /// Receive an encoded frame from the inner `io::Read`, decode it + /// and return the payload. + pub fn recv(&mut self) -> Result { + unimplemented!() + } +}