Skip to content
Closed
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
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub mod ser;
#[doc(inline)]
pub use self::de::{from_slice, from_str};
#[doc(inline)]
pub use self::ser::{to_string, to_vec};
pub use self::ser::{to_string, to_vec, to_slice};

#[allow(deprecated)]
unsafe fn uninitialized<T>() -> T {
Expand Down
10 changes: 4 additions & 6 deletions src/ser/map.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use serde::ser;

use heapless::ArrayLength;

use crate::ser::{Error, Result, Serializer};
use crate::{ser::slice::MutSlice, ser::{Error, Result, Serializer}};

pub struct SerializeMap<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
ser: &'a mut Serializer<B>,
first: bool,
}

impl<'a, B> SerializeMap<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
pub(crate) fn new(ser: &'a mut Serializer<B>) -> Self {
SerializeMap { ser, first: true }
Expand All @@ -23,7 +21,7 @@ where

impl<'a, B> ser::SerializeMap for SerializeMap<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
type Ok = ();
type Error = Error;
Expand Down
32 changes: 22 additions & 10 deletions src/ser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use heapless::{consts::*, String, Vec};
use self::map::SerializeMap;
use self::seq::SerializeSeq;
use self::struct_::SerializeStruct;
use self::slice::{Slice, MutSlice, VecSlice};
mod slice;

mod map;
mod seq;
Expand Down Expand Up @@ -53,17 +55,17 @@ impl fmt::Display for Error {

pub(crate) struct Serializer<B>
where
B: heapless::ArrayLength<u8>,
B: MutSlice,
{
buf: Vec<u8, B>,
buf: B,
}

impl<B> Serializer<B>
where
B: heapless::ArrayLength<u8>,
B: MutSlice,
{
fn new() -> Self {
Serializer { buf: Vec::new() }
fn new(buf: B) -> Self {
Serializer { buf }
}
}

Expand Down Expand Up @@ -136,7 +138,7 @@ macro_rules! serialize_fmt {

impl<'a, B> ser::Serializer for &'a mut Serializer<B>
where
B: heapless::ArrayLength<u8>,
B: MutSlice,
{
type Ok = ();
type Error = Error;
Expand Down Expand Up @@ -338,9 +340,9 @@ where
B: heapless::ArrayLength<u8>,
T: ser::Serialize + ?Sized,
{
let mut ser = Serializer::new();
let mut ser = Serializer::new(VecSlice::new());
value.serialize(&mut ser)?;
Ok(unsafe { String::from_utf8_unchecked(ser.buf) })
Ok(unsafe { String::from_utf8_unchecked(ser.buf.release()) })
}

/// Serializes the given data structure as a JSON byte vector
Expand All @@ -349,9 +351,19 @@ where
B: heapless::ArrayLength<u8>,
T: ser::Serialize + ?Sized,
{
let mut ser = Serializer::new();
let mut ser = Serializer::new(VecSlice::new());
value.serialize(&mut ser)?;
Ok(ser.buf.release())
}

/// Serializes the given data structure as a JSON byte slice
pub fn to_slice<'a, T>(slice: &'a mut [u8], value: &T) -> Result<&'a mut [u8]>
where
T: ser::Serialize + ?Sized,
{
let mut ser = Serializer::new(Slice::new(slice));
value.serialize(&mut ser)?;
Ok(ser.buf)
Ok(ser.buf.release())
}

impl ser::Error for Error {
Expand Down
12 changes: 5 additions & 7 deletions src/ser/seq.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use serde::ser;

use heapless::ArrayLength;

use crate::ser::{Error, Result, Serializer};
use crate::{ser::slice::MutSlice, ser::{Error, Result, Serializer}};

pub struct SerializeSeq<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
de: &'a mut Serializer<B>,
first: bool,
}

impl<'a, B> SerializeSeq<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
pub(crate) fn new(de: &'a mut Serializer<B>) -> Self {
SerializeSeq { de, first: true }
Expand All @@ -23,7 +21,7 @@ where

impl<'a, B> ser::SerializeSeq for SerializeSeq<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
type Ok = ();
type Error = Error;
Expand All @@ -49,7 +47,7 @@ where

impl<'a, B> ser::SerializeTuple for SerializeSeq<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
type Ok = ();
type Error = Error;
Expand Down
73 changes: 73 additions & 0 deletions src/ser/slice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
pub trait MutSlice {
type Output;

fn push(&mut self, b: u8) -> Result<(), u8>;
fn extend_from_slice(&mut self, slice: &[u8]) -> Result<(), ()>;
fn release(self) -> Self::Output;
}

pub struct Slice<'a> {
buf: &'a mut [u8],
index: usize,
}

impl<'a> Slice<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Slice { buf, index: 0 }
}
}

impl<'a> MutSlice for Slice<'a> {
type Output = &'a mut [u8];
fn push(&mut self, b: u8) -> Result<(), u8> {
if self.index >= self.buf.len() {
return Err(b);
}

self.buf[self.index] = b;
self.index += 1;
Ok(())
}

fn extend_from_slice(&mut self, slice: &[u8]) -> Result<(), ()> {
if self.index + slice.len() >= self.buf.len() {
return Err(());
}
self.buf[self.index..self.index + slice.len()].copy_from_slice(slice);
self.index += slice.len();
Ok(())
}

fn release(self) -> Self::Output {
let (used, _unused) = self.buf.split_at_mut(self.index);

used
}
}

use heapless::Vec;

pub struct VecSlice<B: heapless::ArrayLength<u8>>(pub Vec<u8, B>);

impl<B> VecSlice<B>
where
B: heapless::ArrayLength<u8>,
{
pub fn new() -> Self {
VecSlice(Vec::new())
}
}

impl<B: heapless::ArrayLength<u8>> MutSlice for VecSlice<B> {
type Output = Vec<u8, B>;
fn push(&mut self, b: u8) -> Result<(), u8> {
self.0.push(b)
}

fn extend_from_slice(&mut self, slice: &[u8]) -> Result<(), ()> {
self.0.extend_from_slice(slice)
}
fn release(self) -> Self::Output {
self.0
}
}
10 changes: 4 additions & 6 deletions src/ser/struct_.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use serde::ser;

use heapless::ArrayLength;

use crate::ser::{Error, Result, Serializer};
use crate::{ser::slice::MutSlice, ser::{Error, Result, Serializer}};

pub struct SerializeStruct<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
ser: &'a mut Serializer<B>,
first: bool,
}

impl<'a, B> SerializeStruct<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
pub(crate) fn new(ser: &'a mut Serializer<B>) -> Self {
SerializeStruct { ser, first: true }
Expand All @@ -23,7 +21,7 @@ where

impl<'a, B> ser::SerializeStruct for SerializeStruct<'a, B>
where
B: ArrayLength<u8>,
B: MutSlice,
{
type Ok = ();
type Error = Error;
Expand Down