Skip to content

Commit 7959658

Browse files
committed
Add a to_slice function when serializing, that allows serialization into an external buffer, eliminating the need for an additional copy in some cases. Fixes #35
1 parent 238c8fe commit 7959658

File tree

5 files changed

+102
-99
lines changed

5 files changed

+102
-99
lines changed

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub mod ser;
7474
#[doc(inline)]
7575
pub use self::de::{from_slice, from_str};
7676
#[doc(inline)]
77-
pub use self::ser::{to_string, to_vec};
77+
pub use self::ser::{to_slice, to_string, to_vec};
7878

7979
#[allow(deprecated)]
8080
unsafe fn uninitialized<T>() -> T {

src/ser/map.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,24 @@
11
use serde::ser;
22

3-
use heapless::ArrayLength;
4-
53
use crate::ser::{Error, Result, Serializer};
64

7-
pub struct SerializeMap<'a, B>
8-
where
9-
B: ArrayLength<u8>,
10-
{
11-
ser: &'a mut Serializer<B>,
5+
pub struct SerializeMap<'a, 'b> {
6+
ser: &'a mut Serializer<'b>,
127
first: bool,
138
}
149

15-
impl<'a, B> SerializeMap<'a, B>
16-
where
17-
B: ArrayLength<u8>,
18-
{
19-
pub(crate) fn new(ser: &'a mut Serializer<B>) -> Self {
10+
impl<'a, 'b: 'a> SerializeMap<'a, 'b> {
11+
pub(crate) fn new(ser: &'a mut Serializer<'b>) -> Self {
2012
SerializeMap { ser, first: true }
2113
}
2214
}
2315

24-
impl<'a, B> ser::SerializeMap for SerializeMap<'a, B>
25-
where
26-
B: ArrayLength<u8>,
27-
{
16+
impl<'a, 'b: 'a> ser::SerializeMap for SerializeMap<'a, 'b> {
2817
type Ok = ();
2918
type Error = Error;
3019

3120
fn end(self) -> Result<Self::Ok> {
32-
self.ser.buf.push(b'}')?;
21+
self.ser.push(b'}')?;
3322
Ok(())
3423
}
3524

@@ -38,11 +27,11 @@ where
3827
T: ser::Serialize,
3928
{
4029
if !self.first {
41-
self.ser.buf.push(b',')?;
30+
self.ser.push(b',')?;
4231
}
4332
self.first = false;
4433
key.serialize(&mut *self.ser)?;
45-
self.ser.buf.extend_from_slice(b":")?;
34+
self.ser.extend_from_slice(b":")?;
4635
Ok(())
4736
}
4837

src/ser/mod.rs

Lines changed: 75 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub type Result<T> = ::core::result::Result<T, Error>;
2222
pub enum Error {
2323
/// Buffer is full
2424
BufferFull,
25+
/// Buffer is full
26+
Test(usize),
2527
#[doc(hidden)]
2628
__Extensible,
2729
}
@@ -51,19 +53,40 @@ impl fmt::Display for Error {
5153
}
5254
}
5355

54-
pub(crate) struct Serializer<B>
55-
where
56-
B: heapless::ArrayLength<u8>,
57-
{
58-
buf: Vec<u8, B>,
56+
pub(crate) struct Serializer<'a> {
57+
buf: &'a mut [u8],
58+
idx: usize,
5959
}
6060

61-
impl<B> Serializer<B>
62-
where
63-
B: heapless::ArrayLength<u8>,
64-
{
65-
fn new() -> Self {
66-
Serializer { buf: Vec::new() }
61+
impl<'a> Serializer<'a> {
62+
fn new(buf: &'a mut [u8]) -> Self {
63+
Serializer { buf, idx: 0 }
64+
}
65+
66+
fn push(&mut self, c: u8) -> Result<()> {
67+
if self.idx < self.buf.len() {
68+
unsafe { self.push_unchecked(c) };
69+
Ok(())
70+
} else {
71+
Err(Error::BufferFull)
72+
}
73+
}
74+
75+
unsafe fn push_unchecked(&mut self, c: u8) {
76+
self.buf[self.idx] = c;
77+
self.idx += 1;
78+
}
79+
80+
fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> {
81+
if self.idx + other.len() > self.buf.len() {
82+
// won't fit in the buf; don't modify anything and return an error
83+
Err(Error::Test(self.buf.len()))
84+
} else {
85+
for c in other {
86+
unsafe { self.push_unchecked(c.clone()) };
87+
}
88+
Ok(())
89+
}
6790
}
6891
}
6992

@@ -86,7 +109,7 @@ macro_rules! serialize_unsigned {
86109
}
87110
}
88111

89-
$self.buf.extend_from_slice(&buf[i..])?;
112+
$self.extend_from_slice(&buf[i..])?;
90113
Ok(())
91114
}};
92115
}
@@ -120,7 +143,7 @@ macro_rules! serialize_signed {
120143
} else {
121144
i += 1;
122145
}
123-
$self.buf.extend_from_slice(&buf[i..])?;
146+
$self.extend_from_slice(&buf[i..])?;
124147
Ok(())
125148
}};
126149
}
@@ -129,30 +152,27 @@ macro_rules! serialize_fmt {
129152
($self:ident, $uxx:ident, $fmt:expr, $v:expr) => {{
130153
let mut s: String<$uxx> = String::new();
131154
write!(&mut s, $fmt, $v).unwrap();
132-
$self.buf.extend_from_slice(s.as_bytes())?;
155+
$self.extend_from_slice(s.as_bytes())?;
133156
Ok(())
134157
}};
135158
}
136159

137-
impl<'a, B> ser::Serializer for &'a mut Serializer<B>
138-
where
139-
B: heapless::ArrayLength<u8>,
140-
{
160+
impl<'a, 'b: 'a> ser::Serializer for &'a mut Serializer<'b> {
141161
type Ok = ();
142162
type Error = Error;
143-
type SerializeSeq = SerializeSeq<'a, B>;
144-
type SerializeTuple = SerializeSeq<'a, B>;
163+
type SerializeSeq = SerializeSeq<'a, 'b>;
164+
type SerializeTuple = SerializeSeq<'a, 'b>;
145165
type SerializeTupleStruct = Unreachable;
146166
type SerializeTupleVariant = Unreachable;
147-
type SerializeMap = SerializeMap<'a, B>;
148-
type SerializeStruct = SerializeStruct<'a, B>;
167+
type SerializeMap = SerializeMap<'a, 'b>;
168+
type SerializeStruct = SerializeStruct<'a, 'b>;
149169
type SerializeStructVariant = Unreachable;
150170

151171
fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
152172
if v {
153-
self.buf.extend_from_slice(b"true")?;
173+
self.extend_from_slice(b"true")?;
154174
} else {
155-
self.buf.extend_from_slice(b"false")?;
175+
self.extend_from_slice(b"false")?;
156176
}
157177

158178
Ok(())
@@ -211,9 +231,9 @@ where
211231
}
212232

213233
fn serialize_str(self, v: &str) -> Result<Self::Ok> {
214-
self.buf.push(b'"')?;
215-
self.buf.extend_from_slice(v.as_bytes())?;
216-
self.buf.push(b'"')?;
234+
self.push(b'"')?;
235+
self.extend_from_slice(v.as_bytes())?;
236+
self.push(b'"')?;
217237
Ok(())
218238
}
219239

@@ -222,7 +242,7 @@ where
222242
}
223243

224244
fn serialize_none(self) -> Result<Self::Ok> {
225-
self.buf.extend_from_slice(b"null")?;
245+
self.extend_from_slice(b"null")?;
226246
Ok(())
227247
}
228248

@@ -275,7 +295,7 @@ where
275295
}
276296

277297
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
278-
self.buf.push(b'[')?;
298+
self.push(b'[')?;
279299

280300
Ok(SerializeSeq::new(self))
281301
}
@@ -303,13 +323,13 @@ where
303323
}
304324

305325
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
306-
self.buf.push(b'{')?;
326+
self.push(b'{')?;
307327

308328
Ok(SerializeMap::new(self))
309329
}
310330

311331
fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
312-
self.buf.push(b'{')?;
332+
self.push(b'{')?;
313333

314334
Ok(SerializeStruct::new(self))
315335
}
@@ -338,9 +358,7 @@ where
338358
B: heapless::ArrayLength<u8>,
339359
T: ser::Serialize + ?Sized,
340360
{
341-
let mut ser = Serializer::new();
342-
value.serialize(&mut ser)?;
343-
Ok(unsafe { String::from_utf8_unchecked(ser.buf) })
361+
Ok(unsafe { String::from_utf8_unchecked(to_vec(value)?) })
344362
}
345363

346364
/// Serializes the given data structure as a JSON byte vector
@@ -349,9 +367,21 @@ where
349367
B: heapless::ArrayLength<u8>,
350368
T: ser::Serialize + ?Sized,
351369
{
352-
let mut ser = Serializer::new();
370+
let mut buf = Vec::<u8, B>::new();
371+
buf.resize_default(B::to_usize())?;
372+
let len = to_slice(value, &mut buf)?;
373+
buf.truncate(len);
374+
Ok(buf)
375+
}
376+
377+
/// Serializes the given data structure as a JSON byte vector into the provided buffer
378+
pub fn to_slice<T>(value: &T, buf: &mut [u8]) -> Result<usize>
379+
where
380+
T: ser::Serialize + ?Sized,
381+
{
382+
let mut ser = Serializer::new(buf);
353383
value.serialize(&mut ser)?;
354-
Ok(ser.buf)
384+
Ok(ser.idx)
355385
}
356386

357387
impl ser::Error for Error {
@@ -440,11 +470,20 @@ mod tests {
440470

441471
#[test]
442472
fn array() {
473+
let buf = &mut [0u8; 128];
474+
let len = crate::to_slice(&[0, 1, 2], buf).unwrap();
475+
assert_eq!(len, 7);
476+
assert_eq!(&buf[..len], b"[0,1,2]");
443477
assert_eq!(&*crate::to_string::<N, _>(&[0, 1, 2]).unwrap(), "[0,1,2]");
444478
}
445479

446480
#[test]
447481
fn bool() {
482+
let buf = &mut [0u8; 128];
483+
let len = crate::to_slice(&true, buf).unwrap();
484+
assert_eq!(len, 4);
485+
assert_eq!(&buf[..len], b"true");
486+
448487
assert_eq!(&*crate::to_string::<N, _>(&true).unwrap(), "true");
449488
}
450489

src/ser/seq.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,19 @@
11
use serde::ser;
22

3-
use heapless::ArrayLength;
4-
53
use crate::ser::{Error, Result, Serializer};
64

7-
pub struct SerializeSeq<'a, B>
8-
where
9-
B: ArrayLength<u8>,
10-
{
11-
de: &'a mut Serializer<B>,
5+
pub struct SerializeSeq<'a, 'b> {
6+
de: &'a mut Serializer<'b>,
127
first: bool,
138
}
149

15-
impl<'a, B> SerializeSeq<'a, B>
16-
where
17-
B: ArrayLength<u8>,
18-
{
19-
pub(crate) fn new(de: &'a mut Serializer<B>) -> Self {
10+
impl<'a, 'b: 'a> SerializeSeq<'a, 'b> {
11+
pub(crate) fn new(de: &'a mut Serializer<'b>) -> Self {
2012
SerializeSeq { de, first: true }
2113
}
2214
}
2315

24-
impl<'a, B> ser::SerializeSeq for SerializeSeq<'a, B>
25-
where
26-
B: ArrayLength<u8>,
27-
{
16+
impl<'a, 'b: 'a> ser::SerializeSeq for SerializeSeq<'a, 'b> {
2817
type Ok = ();
2918
type Error = Error;
3019

@@ -33,7 +22,7 @@ where
3322
T: ser::Serialize,
3423
{
3524
if !self.first {
36-
self.de.buf.push(b',')?;
25+
self.de.push(b',')?;
3726
}
3827
self.first = false;
3928

@@ -42,15 +31,12 @@ where
4231
}
4332

4433
fn end(self) -> Result<Self::Ok> {
45-
self.de.buf.push(b']')?;
34+
self.de.push(b']')?;
4635
Ok(())
4736
}
4837
}
4938

50-
impl<'a, B> ser::SerializeTuple for SerializeSeq<'a, B>
51-
where
52-
B: ArrayLength<u8>,
53-
{
39+
impl<'a, 'b: 'a> ser::SerializeTuple for SerializeSeq<'a, 'b> {
5440
type Ok = ();
5541
type Error = Error;
5642

0 commit comments

Comments
 (0)