Skip to content
This repository was archived by the owner on Aug 15, 2021. It is now read-only.

Implement 'to_vec' and 'from_slice' for no_std #147

Merged
merged 1 commit into from
Sep 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ before_script:
- rustup target add thumbv7em-none-eabihf # Any target that does not have a standard library will do
script:
- cargo fmt --all -- --check
- (rustup component add clippy && cargo clippy --all --all-features -- -D clippy::all) || true
- (rustup component add clippy && cargo clippy --all -- -D clippy::all) || true
- cargo build
- cargo test
- cargo build --no-default-features --target thumbv7em-none-eabihf # Test we can build a platform that does not have std.
- cargo build --no-default-features --features alloc --target thumbv7em-none-eabihf # Test we can build a platform that does not have std.
- cargo test --no-default-features --lib --tests # Run no_std tests
- [[ $TRAVIS_RUST_VERSION != "1.31.0" ]] && cargo build --no-default-features --features alloc
- cargo build --features unsealed_read_write # The crate should still build when the unsealed_read_write feature is enabled.
- cargo build --no-default-features --features unsealed_read_write # The crate should still build when the unsealed_read_write feature is enabled and std disabled.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@ serde_derive = { version = "1.0.14", default-features = false }

[features]
default = ["std"]
# Uses `alloc` library and adds support for vector functions with
# `no_std`.
alloc = ["serde/alloc"]
std = ["serde/std" ]
unsealed_read_write = []
11 changes: 6 additions & 5 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ use crate::error::{Error, ErrorCode, Result};
use crate::read::EitherLifetime;
#[cfg(feature = "unsealed_read_write")]
pub use crate::read::EitherLifetime;
use crate::read::Offset;
#[cfg(feature = "std")]
pub use crate::read::{IoRead, SliceRead};
pub use crate::read::IoRead;
use crate::read::Offset;
#[cfg(any(feature = "std", feature = "alloc"))]
pub use crate::read::SliceRead;
pub use crate::read::{MutSliceRead, Read, SliceReadFixed};

/// Decodes a value from CBOR data in a slice.
///
/// # Examples
Expand All @@ -41,7 +42,7 @@ pub use crate::read::{MutSliceRead, Read, SliceReadFixed};
/// let value: &str = de::from_slice(&v[..]).unwrap();
/// assert_eq!(value, "foobar");
/// ```
#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_slice<'a, T>(slice: &'a [u8]) -> Result<T>
where
T: de::Deserialize<'a>,
Expand Down Expand Up @@ -144,7 +145,7 @@ where
}
}

#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> Deserializer<SliceRead<'a>> {
/// Constructs a `Deserializer` which reads from a slice.
///
Expand Down
28 changes: 25 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,19 @@
//! serde_cbor = { version = "0.10", default-features = false }
//! ```
//!
//! Without the `std` feature the functions [from_reader], [from_slice], [to_vec], and [to_writer]
//! are not exported. To export [from_slice] and [to_vec] enable the `alloc` feature. The `alloc`
//! feature uses the [`alloc` library][alloc-lib] and requires at least version 1.36.0 of Rust.
//!
//! [alloc-lib]: https://doc.rust-lang.org/alloc/
//!
//! *Note*: to use derive macros in serde you will need to declare `serde`
//! dependency like so:
//! ``` toml
//! serde = { version = "1.0", default-features = false, features = ["derive"] }
//! ```
//!
//! Serialize an object.
//! Serialize an object with `no_std` and without `alloc`.
//! ``` rust
//! # #[macro_use] extern crate serde_derive;
//! # fn main() -> Result<(), serde_cbor::Error> {
Expand Down Expand Up @@ -258,6 +264,9 @@
#[cfg(all(not(feature = "std"), test))]
extern crate std;

#[cfg(feature = "alloc")]
extern crate alloc;

pub mod de;
pub mod error;
mod read;
Expand All @@ -270,18 +279,31 @@ pub mod value;
// Re-export the [items recommended by serde](https://serde.rs/conventions.html).
#[doc(inline)]
pub use crate::de::{Deserializer, StreamDeserializer};

#[doc(inline)]
pub use crate::error::{Error, Result};

#[doc(inline)]
pub use crate::ser::Serializer;

// Convenience functions for serialization and deserialization.
// These functions are only available in `std` mode.
#[cfg(feature = "std")]
#[doc(inline)]
pub use crate::de::{from_reader, from_slice};
pub use crate::de::from_reader;

#[cfg(any(feature = "std", feature = "alloc"))]
#[doc(inline)]
pub use crate::de::from_slice;

#[cfg(any(feature = "std", feature = "alloc"))]
#[doc(inline)]
pub use crate::ser::to_vec;

#[cfg(feature = "std")]
#[doc(inline)]
pub use crate::ser::{to_vec, to_writer};
pub use crate::ser::to_writer;

// Re-export the value type like serde_json
#[cfg(feature = "std")]
#[doc(inline)]
Expand Down
15 changes: 10 additions & 5 deletions src/read.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "alloc")]
use alloc::{vec, vec::Vec};
#[cfg(feature = "std")]
use core::cmp;
use core::mem;
Expand Down Expand Up @@ -284,15 +286,15 @@ where
}

/// A CBOR input source that reads from a slice of bytes.
#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Debug)]
pub struct SliceRead<'a> {
slice: &'a [u8],
scratch: Vec<u8>,
index: usize,
}

#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> SliceRead<'a> {
/// Creates a CBOR input source to read from a slice of bytes.
pub fn new(slice: &'a [u8]) -> SliceRead<'a> {
Expand All @@ -314,18 +316,21 @@ impl<'a> SliceRead<'a> {
}
}

#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> Offset for SliceRead<'a> {
#[inline]
fn byte_offset(&self) -> usize {
self.index
}
}

#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
#[cfg(all(
any(feature = "std", feature = "alloc"),
not(feature = "unsealed_read_write")
))]
impl<'a> private::Sealed for SliceRead<'a> {}

#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a> Read<'a> for SliceRead<'a> {
#[inline]
fn next(&mut self) -> Result<Option<u8>> {
Expand Down
7 changes: 5 additions & 2 deletions src/ser.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Serialize a Rust data structure to CBOR data.

#[cfg(feature = "alloc")]
use alloc::vec::Vec;

#[cfg(feature = "std")]
pub use crate::write::IoWrite;
pub use crate::write::{SliceWrite, Write};
Expand All @@ -12,13 +15,13 @@ use serde::ser::{self, Serialize};
use std::io;

/// Serializes a value to a vector.
#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
where
T: ser::Serialize,
{
let mut vec = Vec::new();
to_writer(&mut vec, value)?;
value.serialize(&mut Serializer::new(&mut vec))?;
Ok(vec)
}

Expand Down
15 changes: 10 additions & 5 deletions src/write.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
#[cfg(not(feature = "std"))]
use core::fmt;
#[cfg(feature = "std")]
Expand Down Expand Up @@ -90,17 +92,20 @@ impl<W: io::Write> Write for IoWrite<W> {
#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
impl<W> private::Sealed for IoWrite<W> where W: io::Write {}

// TODO this should be possible with just alloc
#[cfg(feature = "std")]
#[cfg(any(feature = "std", feature = "alloc"))]
impl Write for Vec<u8> {
type Error = io::Error;
type Error = error::Error;

fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
io::Write::write_all(self, buf)
self.extend_from_slice(buf);
Ok(())
}
}

#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
#[cfg(all(
any(feature = "std", feature = "alloc"),
not(feature = "unsealed_read_write")
))]
impl private::Sealed for Vec<u8> {}

#[cfg(not(feature = "std"))]
Expand Down