Skip to content

Commit 3da0611

Browse files
authored
Merge pull request #68 from quartiq/rj/maybeuninit
MaybeUninit, serde StdError, unittests
2 parents 3792317 + f1a9754 commit 3da0611

File tree

6 files changed

+62
-27
lines changed

6 files changed

+62
-27
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121

2222
include:
2323
# Test MSRV
24-
- rust: 1.51.0
24+
- rust: 1.55.0 # keep in sync with manifest rust-version
2525
TARGET: x86_64-unknown-linux-gnu
2626

2727
# Test nightly but don't fail

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1313
`NEG_INFINITY`) to result in JSON `null`. This matches `serde_json` behavior.
1414
- Changed deserialization of JSON `null` where `f32`/`f64` is expected to result in
1515
the respective `NAN`.
16+
- [breaking-change] increase MSRV to Rust `1.55.0` due to `maybe_uninit_extra`.
1617

1718
## [v0.4.0] - 2021-05-08
1819

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ categories = ["no-std"]
44
description = "serde-json for no_std programs"
55
documentation = "https://docs.rs/serde-json-core"
66
edition = "2018"
7+
rust-version = "1.55.0" # keep in sync with ci
78
keywords = ["serde", "json"]
89
license = "MIT OR Apache-2.0"
910
name = "serde-json-core"
@@ -20,10 +21,10 @@ optional = true
2021

2122
[dependencies.serde]
2223
default-features = false
23-
version = "1.0.80"
24+
version = "1.0.100"
2425

2526
[dev-dependencies]
26-
serde_derive = "1.0.80"
27+
serde_derive = "1.0.100"
2728

2829
[features]
2930
default = ["heapless"]

src/de/mod.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,7 @@ pub enum Error {
7777
CustomErrorWithMessage(heapless::String<64>),
7878
}
7979

80-
#[cfg(feature = "std")]
81-
impl ::std::error::Error for Error {
82-
fn description(&self) -> &str {
83-
""
84-
}
85-
}
80+
impl serde::de::StdError for Error {}
8681

8782
pub(crate) struct Deserializer<'b> {
8883
slice: &'b [u8],
@@ -1090,6 +1085,46 @@ mod tests {
10901085
);
10911086
}
10921087

1088+
#[test]
1089+
fn struct_with_array_field() {
1090+
#[derive(Debug, Deserialize, PartialEq)]
1091+
struct Test {
1092+
status: bool,
1093+
point: [u32; 3],
1094+
}
1095+
1096+
assert_eq!(
1097+
crate::from_str(r#"{ "status": true, "point": [1, 2, 3] }"#),
1098+
Ok((
1099+
Test {
1100+
status: true,
1101+
point: [1, 2, 3]
1102+
},
1103+
38
1104+
))
1105+
);
1106+
}
1107+
1108+
#[test]
1109+
fn struct_with_tuple_field() {
1110+
#[derive(Debug, Deserialize, PartialEq)]
1111+
struct Test {
1112+
status: bool,
1113+
point: (u32, u32, u32),
1114+
}
1115+
1116+
assert_eq!(
1117+
crate::from_str(r#"{ "status": true, "point": [1, 2, 3] }"#),
1118+
Ok((
1119+
Test {
1120+
status: true,
1121+
point: (1, 2, 3)
1122+
},
1123+
38
1124+
))
1125+
);
1126+
}
1127+
10931128
#[test]
10941129
fn ignoring_extra_fields() {
10951130
#[derive(Debug, Deserialize, PartialEq)]

src/lib.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,3 @@ pub use self::ser::{to_string, to_vec};
7171

7272
#[cfg(feature = "heapless")]
7373
pub use heapless;
74-
75-
#[allow(deprecated)]
76-
unsafe fn uninitialized<T>() -> T {
77-
core::mem::uninitialized()
78-
}

src/ser/mod.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Serialize a Rust data structure into JSON data
22
3+
use core::mem::MaybeUninit;
34
use core::{fmt, str};
45

56
use serde::ser;
@@ -39,12 +40,7 @@ impl From<u8> for Error {
3940
}
4041
}
4142

42-
#[cfg(feature = "std")]
43-
impl ::std::error::Error for Error {
44-
fn description(&self) -> &str {
45-
""
46-
}
47-
}
43+
impl serde::ser::StdError for Error {}
4844

4945
impl fmt::Display for Error {
5046
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -96,12 +92,12 @@ impl<'a> Serializer<'a> {
9692
// which take 200+ bytes of ROM / Flash
9793
macro_rules! serialize_unsigned {
9894
($self:ident, $N:expr, $v:expr) => {{
99-
let mut buf: [u8; $N] = unsafe { super::uninitialized() };
95+
let mut buf: [MaybeUninit<u8>; $N] = [MaybeUninit::uninit(); $N];
10096

10197
let mut v = $v;
10298
let mut i = $N - 1;
10399
loop {
104-
buf[i] = (v % 10) as u8 + b'0';
100+
buf[i].write((v % 10) as u8 + b'0');
105101
v /= 10;
106102

107103
if v == 0 {
@@ -111,7 +107,10 @@ macro_rules! serialize_unsigned {
111107
}
112108
}
113109

114-
$self.extend_from_slice(&buf[i..])
110+
// Note(feature): maybe_uninit_slice
111+
let buf = unsafe { &*(&buf[i..] as *const _ as *const [u8]) };
112+
113+
$self.extend_from_slice(buf)
115114
}};
116115
}
117116

@@ -126,10 +125,10 @@ macro_rules! serialize_signed {
126125
(false, v as $uxx)
127126
};
128127

129-
let mut buf: [u8; $N] = unsafe { super::uninitialized() };
128+
let mut buf: [MaybeUninit<u8>; $N] = [MaybeUninit::uninit(); $N];
130129
let mut i = $N - 1;
131130
loop {
132-
buf[i] = (v % 10) as u8 + b'0';
131+
buf[i].write((v % 10) as u8 + b'0');
133132
v /= 10;
134133

135134
i -= 1;
@@ -140,11 +139,15 @@ macro_rules! serialize_signed {
140139
}
141140

142141
if signed {
143-
buf[i] = b'-';
142+
buf[i].write(b'-');
144143
} else {
145144
i += 1;
146145
}
147-
$self.extend_from_slice(&buf[i..])
146+
147+
// Note(feature): maybe_uninit_slice
148+
let buf = unsafe { &*(&buf[i..] as *const _ as *const [u8]) };
149+
150+
$self.extend_from_slice(buf)
148151
}};
149152
}
150153

0 commit comments

Comments
 (0)