Skip to content

Commit 8e608b6

Browse files
mina86aumetra
authored andcommitted
Make library no_std and introduce std and unstable features
Remove all references to std from the library and introduce std and unstable features which enable corresponding serde features. In default build, std is enabled and nothing changes. However, if std is disabled, the library becomes no_std. Downside of lack of std is that Error enum no longer implements std::error;:Error. To remedy that, unstable feature uses core::error::Error but requires a nightly compiler. For the most part, this commit is mostly just replacing references to std crate with core and alloc crates. On exception is std::error::Error which is replaced by serde’s StdError such that Error enums implement whatever trait serde uses. With std or unstable feature enabled it’s just an alias to {std,core}::error::Error. Issue: CosmWasm/cosmwasm#1484 Issue: #40
1 parent 35c68e5 commit 8e608b6

File tree

9 files changed

+85
-66
lines changed

9 files changed

+85
-66
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,17 @@ project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Changed
1111

12+
- Introduce `std` (enabled by default) and `unstable` features ([#58]). They
13+
enable corresponding serde’s features and if either is enabled, `Error`
14+
implements `std::error::Error` trait. By itself, `serde-json-wasm` is now
15+
`no_std`; it’s up to serde’s features whether the entire build is. **Please
16+
not:** this potentially breaks `default-features = false` builds.
17+
1218
- Serialize / deserialize `u128`/`i128` types as numbers instead of strings
1319
([#59]).<br/> **Please note:** this breaks deserialization of `u128`/`i128`
1420
serialized with older versions of `serde-json-wasm`.
1521

22+
[#58]: https://github.com/CosmWasm/serde-json-wasm/pull/58
1623
[#59]: https://github.com/CosmWasm/serde-json-wasm/pull/59
1724

1825
## [0.5.1] - 2023-04-11

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,14 @@ ryu = "1.0.5"
2727

2828
[dependencies.serde]
2929
default-features = false
30-
features = ["alloc", "derive"]
30+
features = ["alloc"]
3131
version = "1.0.100"
3232

3333
[dev-dependencies]
34-
serde_derive = "1.0.100"
34+
serde = { version = "1.0.100", default-features = false, features = ["derive"] }
3535
serde_json = "1.0.120"
36+
37+
[features]
38+
default = ["std"]
39+
std = ["serde/std"]
40+
unstable = ["serde/unstable"]

src/de/errors.rs

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1-
use serde::{de, Serialize};
2-
use std::{error, fmt};
1+
use alloc::string::{String, ToString};
2+
3+
use serde::de;
34

45
/// Deserialization result
56
pub type Result<T> = core::result::Result<T, Error>;
67

7-
/// This type represents all possible errors that can occur when deserializing JSON data
8-
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
8+
/// This type represents all possible errors that can occur when deserializing
9+
/// JSON data
10+
///
11+
/// It implements [`std::error::Error`] trait so long as either `std` or
12+
/// `unstable` features are enabled. `std` is enabled by default and disabling
13+
/// it makes the crate `no_std`. `unstable` makes sit necessary to build code
14+
/// with nightly compiler.
15+
#[derive(Debug, PartialEq, Eq)]
916
#[non_exhaustive]
1017
pub enum Error {
1118
/// Control character (U+0000 to U+001F) found in string. Those must always be escaped.
@@ -75,27 +82,16 @@ pub enum Error {
7582
Custom(String),
7683
}
7784

78-
impl error::Error for Error {
79-
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
80-
None
81-
}
82-
83-
fn description(&self) -> &str {
84-
"(use display)"
85-
}
86-
}
85+
impl de::StdError for Error {}
8786

8887
impl de::Error for Error {
89-
fn custom<T>(msg: T) -> Self
90-
where
91-
T: fmt::Display,
92-
{
88+
fn custom<T: core::fmt::Display>(msg: T) -> Self {
9389
Error::Custom(msg.to_string())
9490
}
9591
}
9692

97-
impl fmt::Display for Error {
98-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93+
impl core::fmt::Display for Error {
94+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9995
write!(
10096
f,
10197
"{}",

src/de/mod.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@ mod map;
66
mod seq;
77
mod unescape;
88

9+
use alloc::string::String;
10+
911
pub use errors::{Error, Result};
1012

11-
use std::str::{self, FromStr};
13+
use core::str::{self, FromStr};
1214

1315
use serde::de::{self, Visitor};
1416

1517
use self::enum_::{UnitVariantAccess, VariantAccess};
1618
use self::map::MapAccess;
1719
use self::seq::SeqAccess;
18-
use std::str::from_utf8;
1920

2021
/// Deserializer will parse serde-json-wasm flavored JSON into a
2122
/// serde-annotated struct
@@ -131,7 +132,7 @@ impl<'a> Deserializer<'a> {
131132
)?))
132133
} else {
133134
Ok(StringLike::Borrowed(
134-
from_utf8(&self.slice[start..end])
135+
core::str::from_utf8(&self.slice[start..end])
135136
.map_err(|_| Error::InvalidUnicodeCodePoint)?,
136137
))
137138
};
@@ -697,7 +698,12 @@ where
697698
#[cfg(test)]
698699
mod tests {
699700
use super::from_str;
700-
use serde_derive::{Deserialize, Serialize};
701+
702+
use alloc::string::{String, ToString};
703+
use alloc::vec;
704+
use alloc::vec::Vec;
705+
706+
use serde::{Deserialize, Serialize};
701707

702708
#[derive(Debug, Deserialize, PartialEq)]
703709
enum Type {
@@ -895,7 +901,7 @@ mod tests {
895901
fn integer() {
896902
assert_eq!(from_str("5"), Ok(5));
897903
assert_eq!(from_str("101"), Ok(101));
898-
assert!(dbg!(from_str::<u16>("1e5")).is_err());
904+
assert!(from_str::<u16>("1e5").is_err());
899905
assert!(from_str::<u8>("256").is_err());
900906
assert!(from_str::<f32>(",").is_err());
901907
}
@@ -1331,7 +1337,7 @@ mod tests {
13311337

13321338
#[test]
13331339
fn numbered_key_maps() {
1334-
use std::collections::BTreeMap;
1340+
use alloc::collections::BTreeMap;
13351341

13361342
// u8
13371343
let mut ranking: BTreeMap<u8, String> = BTreeMap::new();
@@ -1432,7 +1438,7 @@ mod tests {
14321438
pub messages: Vec<Msg>,
14331439
}
14341440

1435-
#[derive(Debug, Deserialize, PartialEq, Eq, serde_derive::Serialize)]
1441+
#[derive(Debug, Deserialize, PartialEq, Eq, serde::Serialize)]
14361442
pub struct Msg {
14371443
pub name: String,
14381444
}

src/de/unescape.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use std::convert::TryFrom;
1+
use alloc::string::String;
2+
use alloc::vec::Vec;
3+
use core::convert::TryFrom;
24

35
use super::errors::{Error, Result};
46

src/lib.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,15 @@
5656
#![deny(missing_docs)]
5757
#![deny(rust_2018_compatibility)]
5858
#![deny(rust_2018_idioms)]
59-
#![cfg_attr(not(feature = "std"), no_std)]
59+
// Note: Even though we declare the crate as `no_std`, by default `std` feature
60+
// is enabled which enables serde’s `std` feature which makes our dependency
61+
// non-`no_std`. This `no_std` declaration only makes sure that our code
62+
// doesn’t depend on `std` directly (except for tests).
63+
#![no_std]
64+
65+
extern crate alloc;
66+
#[cfg(test)]
67+
extern crate std;
6068

6169
pub mod de;
6270
pub mod ser;
@@ -67,10 +75,14 @@ pub use self::ser::{to_string, to_vec};
6775

6876
#[cfg(test)]
6977
mod test {
70-
use std::collections::BTreeMap;
78+
use alloc::borrow::ToOwned;
79+
use alloc::collections::BTreeMap;
80+
use alloc::string::{String, ToString};
81+
use alloc::vec;
82+
use alloc::vec::Vec;
7183

7284
use super::*;
73-
use serde_derive::{Deserialize, Serialize};
85+
use serde::{Deserialize, Serialize};
7486

7587
#[derive(Debug, Deserialize, Serialize, PartialEq)]
7688
struct Address(String);
@@ -106,7 +118,7 @@ mod test {
106118
fn can_serde() {
107119
let min = Item {
108120
model: Model::Comment,
109-
title: "".to_string(),
121+
title: String::new(),
110122
content: None,
111123
list: vec![],
112124
published: false,

src/ser/map.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::fmt;
2-
31
use serde::{ser, Serialize};
42

53
use crate::ser::{Error, Result, Serializer};
@@ -58,7 +56,7 @@ struct MapKeySerializer<'a> {
5856
}
5957

6058
pub(crate) fn key_must_be_a_string() -> Error {
61-
Error::Custom("JSON object key is required to be a string type.".to_string())
59+
Error::Custom("JSON object key is required to be a string type.".into())
6260
}
6361

6462
macro_rules! serialize_unsigned_key {
@@ -255,7 +253,7 @@ impl<'a> ser::Serializer for MapKeySerializer<'a> {
255253

256254
fn collect_str<T>(self, _value: &T) -> Result<()>
257255
where
258-
T: ?Sized + fmt::Display,
256+
T: ?Sized + core::fmt::Display,
259257
{
260258
unreachable!()
261259
}

src/ser/mod.rs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
//! Serialize a Rust data structure into JSON data
22
3-
use std::{error, fmt, str};
3+
use alloc::string::{String, ToString};
4+
use alloc::vec::Vec;
5+
use core::{fmt, str};
46

57
use serde::ser;
68
use serde::ser::SerializeStruct as _;
7-
use serde::Serialize;
8-
9-
use std::vec::Vec;
109

1110
use self::map::SerializeMap;
1211
use self::seq::SerializeSeq;
@@ -20,7 +19,12 @@ mod struct_;
2019
pub type Result<T> = ::core::result::Result<T, Error>;
2120

2221
/// This type represents all possible errors that can occur when serializing JSON data
23-
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
22+
///
23+
/// It implements [`std::error::Error`] trait so long as either `std` or
24+
/// `unstable` features are enabled. `std` is enabled by default and disabling
25+
/// it makes the crate `no_std`. `unstable` makes sit necessary to build code
26+
/// with nightly compiler.
27+
#[derive(Debug)]
2428
#[non_exhaustive]
2529
pub enum Error {
2630
/// Buffer is full
@@ -42,18 +46,10 @@ impl From<u8> for Error {
4246
}
4347
}
4448

45-
impl error::Error for Error {
46-
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
47-
None
48-
}
49+
impl ser::StdError for Error {}
4950

50-
fn description(&self) -> &str {
51-
"(use display)"
52-
}
53-
}
54-
55-
impl fmt::Display for Error {
56-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51+
impl core::fmt::Display for Error {
52+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
5753
match self {
5854
Error::BufferFull => write!(f, "Buffer is full"),
5955
Error::Custom(msg) => write!(f, "{}", &msg),
@@ -479,18 +475,21 @@ where
479475
}
480476

481477
impl ser::Error for Error {
482-
fn custom<T>(msg: T) -> Self
483-
where
484-
T: fmt::Display,
485-
{
478+
fn custom<T: core::fmt::Display>(msg: T) -> Self {
486479
Error::Custom(msg.to_string())
487480
}
488481
}
489482

490483
#[cfg(test)]
491484
mod tests {
492-
493485
use super::to_string;
486+
487+
use alloc::collections::BTreeMap;
488+
use alloc::string::{String, ToString};
489+
use alloc::vec;
490+
use alloc::vec::Vec;
491+
use std::collections::HashMap;
492+
494493
use serde::{Deserialize, Serialize, Serializer};
495494

496495
#[macro_export]
@@ -1085,7 +1084,7 @@ mod tests {
10851084
}
10861085

10871086
let users = Users {
1088-
users: vec!["joe".to_string(), "alice".to_string()],
1087+
users: vec!["joe".into(), "alice".into()],
10891088
pagination: Pagination {
10901089
offset: 100,
10911090
limit: 20,
@@ -1102,8 +1101,6 @@ mod tests {
11021101

11031102
#[test]
11041103
fn btree_map() {
1105-
use std::collections::BTreeMap;
1106-
11071104
// empty map
11081105
let empty = BTreeMap::<(), ()>::new();
11091106
assert_eq!(to_string(&empty).unwrap(), r#"{}"#);
@@ -1225,8 +1222,6 @@ mod tests {
12251222

12261223
#[test]
12271224
fn number_key() {
1228-
use std::collections::HashMap;
1229-
12301225
// i8 key
12311226
let mut map = HashMap::new();
12321227
map.insert(10i8, "my_age");
@@ -1289,7 +1284,6 @@ mod tests {
12891284
#[test]
12901285
fn invalid_json_key() {
12911286
use crate::ser::map::key_must_be_a_string;
1292-
use std::collections::HashMap;
12931287

12941288
#[derive(Debug, Serialize, PartialEq, Eq, Hash)]
12951289
#[serde(rename_all = "lowercase")]
@@ -1345,7 +1339,7 @@ mod tests {
13451339

13461340
#[test]
13471341
fn serialize_embedded_enum() {
1348-
use serde_derive::Deserialize;
1342+
use serde::Deserialize;
13491343

13501344
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
13511345
#[serde(rename_all = "lowercase")]

0 commit comments

Comments
 (0)