Skip to content
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
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ name = "serde-json-core"
version = "0.1.0"

[dependencies]
heapless = "0.2.4"
heapless = "0.4.0"

[dependencies.serde]
default-features = false
version = "1.0.33"
version = "1.0.80"

[dev-dependencies]
serde_derive = "1.0.33"
serde_derive = "1.0.80"

[features]
std = ["serde/std"]
28 changes: 26 additions & 2 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,8 +548,32 @@ impl de::Error for Error {
}

impl fmt::Display for Error {
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
unreachable!()
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", match self {
Error::EofWhileParsingList => "EOF while parsing a list.",
Error::EofWhileParsingObject => "EOF while parsing an object.",
Error::EofWhileParsingString => "EOF while parsing a string.",
Error::EofWhileParsingValue => "EOF while parsing a JSON value.",
Error::ExpectedColon => "Expected this character to be a `':'`.",
Error::ExpectedListCommaOrEnd => "Expected this character to be either a `','` or\
a \
`']'`.",
Error::ExpectedObjectCommaOrEnd => "Expected this character to be either a `','` \
or a \
`'}'`.",
Error::ExpectedSomeIdent => "Expected to parse either a `true`, `false`, or a \
`null`.",
Error::ExpectedSomeValue => "Expected this character to start a JSON value.",
Error::InvalidNumber => "Invalid number.",
Error::InvalidType => "Invalid type",
Error::InvalidUnicodeCodePoint => "Invalid unicode code point.",
Error::KeyMustBeAString => "Object key is not a string.",
Error::TrailingCharacters => "JSON has non-whitespace trailing characters after \
the \
value.",
Error::TrailingComma => "JSON has a comma after the last value in an array or map.",
_ => "Invalid JSON"
})
}
}

Expand Down
68 changes: 38 additions & 30 deletions src/ser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
//! Serialize a Rust data structure into JSON data

use core::marker::Unsize;
use core::{fmt, mem};

use serde::ser;

use heapless::{BufferFullError, String, Vec};
use heapless::{String, Vec};

use self::seq::SerializeSeq;
use self::struct_::SerializeStruct;
Expand All @@ -25,35 +24,43 @@ pub enum Error {
__Extensible,
}

impl From<()> for Error {
fn from(_:()) -> Error {
Error::BufferFull
}
}


impl From<u8> for Error {
fn from(_:u8) -> Error {
Error::BufferFull
}
}

#[cfg(feature = "std")]
impl ::std::error::Error for Error {
fn description(&self) -> &str {
""
}
}

impl From<BufferFullError> for Error {
fn from(_: BufferFullError) -> Self {
Error::BufferFull
}
}

impl fmt::Display for Error {
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
unreachable!()
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Buffer is full")
}
}

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

impl<B> Serializer<B>
where
B: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
{
fn new() -> Self {
Serializer { buf: Vec::new() }
Expand Down Expand Up @@ -120,7 +127,7 @@ macro_rules! serialize_signed {

impl<'a, B> ser::Serializer for &'a mut Serializer<B>
where
B: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
{
type Ok = ();
type Error = Error;
Expand Down Expand Up @@ -317,7 +324,7 @@ where
/// Serializes the given data structure as a string of JSON text
pub fn to_string<B, T>(value: &T) -> Result<String<B>>
where
B: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
T: ser::Serialize + ?Sized,
{
let mut ser = Serializer::new();
Expand All @@ -328,7 +335,7 @@ where
/// Serializes the given data structure as a JSON byte vector
pub fn to_vec<B, T>(value: &T) -> Result<Vec<u8, B>>
where
B: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
T: ser::Serialize + ?Sized,
{
let mut ser = Serializer::new();
Expand Down Expand Up @@ -414,19 +421,20 @@ impl ser::SerializeStructVariant for Unreachable {

#[cfg(test)]
mod tests {
const N: usize = 128;
use heapless::consts::U128;
type N = U128;

#[test]
fn array() {
assert_eq!(
&*super::to_string::<[u8; N], _>(&[0, 1, 2]).unwrap(),
&*super::to_string::<N,_>(&[0, 1, 2]).unwrap(),
"[0,1,2]"
);
}

#[test]
fn bool() {
assert_eq!(&*super::to_string::<[u8; N], _>(&true).unwrap(), "true");
assert_eq!(&*super::to_string::<N, _>(&true).unwrap(), "true");
}

#[test]
Expand All @@ -440,20 +448,20 @@ mod tests {
}

assert_eq!(
&*super::to_string::<[u8; N], _>(&Type::Boolean).unwrap(),
&*super::to_string::<N, _>(&Type::Boolean).unwrap(),
r#""boolean""#
);

assert_eq!(
&*super::to_string::<[u8; N], _>(&Type::Number).unwrap(),
&*super::to_string::<N, _>(&Type::Number).unwrap(),
r#""number""#
);
}

#[test]
fn str() {
assert_eq!(
&*super::to_string::<[u8; N], _>("hello").unwrap(),
&*super::to_string::<N, _>("hello").unwrap(),
r#""hello""#
);
}
Expand All @@ -466,7 +474,7 @@ mod tests {
}

assert_eq!(
&*super::to_string::<[u8; N], _>(&Led { led: true }).unwrap(),
&*super::to_string::<N, _>(&Led { led: true }).unwrap(),
r#"{"led":true}"#
);
}
Expand All @@ -479,22 +487,22 @@ mod tests {
}

assert_eq!(
&*super::to_string::<[u8; N], _>(&Temperature { temperature: 127 }).unwrap(),
&*super::to_string::<N, _>(&Temperature { temperature: 127 }).unwrap(),
r#"{"temperature":127}"#
);

assert_eq!(
&*super::to_string::<[u8; N], _>(&Temperature { temperature: 20 }).unwrap(),
&*super::to_string::<N, _>(&Temperature { temperature: 20 }).unwrap(),
r#"{"temperature":20}"#
);

assert_eq!(
&*super::to_string::<[u8; N], _>(&Temperature { temperature: -17 }).unwrap(),
&*super::to_string::<N, _>(&Temperature { temperature: -17 }).unwrap(),
r#"{"temperature":-17}"#
);

assert_eq!(
&*super::to_string::<[u8; N], _>(&Temperature { temperature: -128 }).unwrap(),
&*super::to_string::<N, _>(&Temperature { temperature: -128 }).unwrap(),
r#"{"temperature":-128}"#
);
}
Expand All @@ -507,15 +515,15 @@ mod tests {
}

assert_eq!(
super::to_string::<[u8; N], _>(&Property {
super::to_string::<N, _>(&Property {
description: Some("An ambient temperature sensor"),
}).unwrap(),
r#"{"description":"An ambient temperature sensor"}"#
);

// XXX Ideally this should produce "{}"
assert_eq!(
super::to_string::<[u8; N], _>(&Property { description: None }).unwrap(),
super::to_string::<N, _>(&Property { description: None }).unwrap(),
r#"{"description":null}"#
);
}
Expand All @@ -528,7 +536,7 @@ mod tests {
}

assert_eq!(
&*super::to_string::<[u8; N], _>(&Temperature { temperature: 20 }).unwrap(),
&*super::to_string::<N, _>(&Temperature { temperature: 20 }).unwrap(),
r#"{"temperature":20}"#
);
}
Expand All @@ -539,7 +547,7 @@ mod tests {
struct Empty {}

assert_eq!(
&*super::to_string::<[u8; N], _>(&Empty {}).unwrap(),
&*super::to_string::<N, _>(&Empty {}).unwrap(),
r#"{}"#
);

Expand All @@ -550,7 +558,7 @@ mod tests {
}

assert_eq!(
&*super::to_string::<[u8; N], _>(&Tuple { a: true, b: false }).unwrap(),
&*super::to_string::<N, _>(&Tuple { a: true, b: false }).unwrap(),
r#"{"a":true,"b":false}"#
);
}
Expand Down
10 changes: 4 additions & 6 deletions src/ser/seq.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use core::marker::Unsize;

use serde::ser;

use ser::{Error, Result, Serializer};

pub struct SerializeSeq<'a, B>
where
B: Unsize<[u8]> + 'a,
B: heapless::ArrayLength<u8> + 'a,
{
de: &'a mut Serializer<B>,
first: bool,
}

impl<'a, B> SerializeSeq<'a, B>
where
B: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
{
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: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
{
type Ok = ();
type Error = Error;
Expand All @@ -49,7 +47,7 @@ where

impl<'a, B> ser::SerializeTuple for SerializeSeq<'a, B>
where
B: Unsize<[u8]>,
B: heapless::ArrayLength<u8>,
{
type Ok = ();
type Error = Error;
Expand Down
8 changes: 3 additions & 5 deletions src/ser/struct_.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
use core::marker::Unsize;

use serde::ser;

use ser::{Error, Result, Serializer};

pub struct SerializeStruct<'a, B>
where
B: Unsize<[u8]> + 'a,
B: heapless::ArrayLength<u8> + 'a,
{
de: &'a mut Serializer<B>,
first: bool,
}

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

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