Interface, dependencies, builds for typed sub-module.
This commit is contained in:
parent
7056eb9187
commit
68428fbd84
5 changed files with 114 additions and 6 deletions
11
Cargo.toml
11
Cargo.toml
|
@ -16,12 +16,21 @@ branch = "master"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cobs = "^0.1.3"
|
cobs = "^0.1.3"
|
||||||
ref_slice = "^1.1.1"
|
ref_slice = "^1.1.1"
|
||||||
|
serde = { version = "^1.0", optional = true }
|
||||||
|
ssmarshal = { version = "^1.0", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
serde_derive = "^1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["use_std"]
|
default = ["use_std", "typed"]
|
||||||
|
|
||||||
# Enable to print all data to stdout for testing.
|
# Enable to print all data to stdout for testing.
|
||||||
trace = []
|
trace = []
|
||||||
|
|
||||||
# Use standard library. Enabled by default, disable for no_std.
|
# Use standard library. Enabled by default, disable for no_std.
|
||||||
use_std = []
|
use_std = []
|
||||||
|
|
||||||
|
# Enables the `typed` sub-module for sending and receiving
|
||||||
|
# structs serialized with serde.
|
||||||
|
typed = ["serde", "ssmarshal"]
|
||||||
|
|
|
@ -8,7 +8,9 @@ rustup toolchain update beta;
|
||||||
rustup toolchain update nightly;
|
rustup toolchain update nightly;
|
||||||
|
|
||||||
cargo +stable build --verbose;
|
cargo +stable build --verbose;
|
||||||
|
cargo +stable build --verbose --no-default-features;
|
||||||
cargo +beta build --verbose;
|
cargo +beta build --verbose;
|
||||||
|
cargo +beta build --verbose --no-default-features;
|
||||||
|
|
||||||
cargo +nightly test --verbose;
|
cargo +nightly test --verbose;
|
||||||
cargo +nightly test --verbose --no-default-features;
|
cargo +nightly test --verbose --no-default-features;
|
||||||
|
|
|
@ -5,6 +5,7 @@ echo "TRAVIS_RUST_VERSION: '${TRAVIS_RUST_VERSION}'"
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
cargo build --verbose;
|
cargo build --verbose;
|
||||||
|
cargo build --verbose --no-default-features;
|
||||||
|
|
||||||
if [[ "${TRAVIS_RUST_VERSION}" == "nightly" ]]; then
|
if [[ "${TRAVIS_RUST_VERSION}" == "nightly" ]]; then
|
||||||
cargo test --verbose;
|
cargo test --verbose;
|
||||||
|
|
13
src/lib.rs
13
src/lib.rs
|
@ -36,6 +36,9 @@
|
||||||
//!
|
//!
|
||||||
//! `trace`: Enable to print all data to stdout for testing.
|
//! `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
|
//! ## API
|
||||||
//!
|
//!
|
||||||
//! Payload data and encoded frame data have separate types to avoid
|
//! 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
|
//! See the `decode_*` and `encode_*` functions for simple uses with
|
||||||
//! various input and output types.
|
//! 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
|
//! efficiently passed as a function argument by reference, but is
|
||||||
//! returned using an opaque struct (`BoxPayload`, `BoxEncoded`)
|
//! returned using an opaque struct (`BoxPayload`, `BoxEncoded`)
|
||||||
//! containing a heap-allocated value instead. Consequently `encode_*`
|
//! containing a heap-allocated value instead. Consequently `encode_*`
|
||||||
|
@ -82,8 +85,11 @@
|
||||||
#![cfg_attr(not(feature = "use_std"), no_std)]
|
#![cfg_attr(not(feature = "use_std"), no_std)]
|
||||||
|
|
||||||
extern crate cobs;
|
extern crate cobs;
|
||||||
|
|
||||||
extern crate ref_slice;
|
extern crate ref_slice;
|
||||||
|
#[cfg(feature = "typed")]
|
||||||
|
extern crate serde;
|
||||||
|
#[cfg(feature = "typed")]
|
||||||
|
extern crate ssmarshal;
|
||||||
|
|
||||||
#[cfg(feature = "use_std")]
|
#[cfg(feature = "use_std")]
|
||||||
use ref_slice::ref_slice_mut;
|
use ref_slice::ref_slice_mut;
|
||||||
|
@ -101,7 +107,8 @@ pub mod error;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use error::{Error, Result};
|
use error::{Error, Result};
|
||||||
|
|
||||||
|
#[cfg(feature = "typed")]
|
||||||
|
pub mod typed;
|
||||||
|
|
||||||
/// Arbitrary user data.
|
/// Arbitrary user data.
|
||||||
pub type Payload = [u8];
|
pub type Payload = [u8];
|
||||||
|
|
89
src/typed.rs
Normal file
89
src/typed.rs
Normal file
|
@ -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: Write, T: Serialize> {
|
||||||
|
w: W,
|
||||||
|
_t: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: Write, T: Serialize> Sender<W, T> {
|
||||||
|
/// Construct a `Sender` that sends encoded structs over the supplied
|
||||||
|
/// `io::Write`.
|
||||||
|
pub fn new(w: W) -> Sender<W, T> {
|
||||||
|
Sender::<W, T> {
|
||||||
|
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<usize> {
|
||||||
|
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<usize> {
|
||||||
|
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: Read, T: DeserializeOwned> {
|
||||||
|
r: R,
|
||||||
|
_t: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<R: Read, T: DeserializeOwned> Receiver<R, T> {
|
||||||
|
/// Construct a `Receiver` that receives encoded structs from the supplied
|
||||||
|
/// `io::Read`.
|
||||||
|
pub fn new(r: R) -> Receiver<R, T> {
|
||||||
|
Receiver::<R, T> {
|
||||||
|
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<T> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue