Skip to content
This repository was archived by the owner on Jul 1, 2025. It is now read-only.

Commit 15b0512

Browse files
committed
chore: split modules
1 parent 8180b37 commit 15b0512

File tree

6 files changed

+191
-136
lines changed

6 files changed

+191
-136
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ name = "detrim"
33
version = "0.1.0"
44
authors = ["Rob Ede <[email protected]>"]
55
description = "String deserializers customization for serde"
6-
categories = ["encoding", "no-std", "no-std::no-alloc"]
6+
categories = ["encoding", "no-std"]
77
keywords = ["deserialization", "utilities", "serde"]
88
repository = "https://github.com/x52dev/detrim"
99
license = "MIT OR Apache-2.0"
1010
edition = "2018"
1111
rust-version = "1.56.1"
1212

1313
[dependencies]
14-
serde = { version = "1", default-features = false }
14+
serde = { version = "1", default-features = false, features = ["alloc"] }
1515

1616
[dev-dependencies]
1717
serde = { version = "1", features = ["std", "derive"] }

justfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ test toolchain="":
2323
# Downgrade dev-dependencies necessary to run MSRV checks/tests.
2424
[private]
2525
downgrade-msrv:
26-
@echo "No MSRV downgrades needed"
26+
cargo update -p=syn --precise="2.0.56"
2727

2828
# Run workspace test suite using MSRV.
2929
test-msrv: downgrade-msrv (test msrv_rustup)

src/lib.rs

Lines changed: 6 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -5,129 +5,10 @@
55

66
extern crate alloc;
77

8-
use alloc::{borrow::ToOwned, string::String};
8+
mod string;
9+
mod string_non_empty;
910

10-
use serde::{de, Deserialize as _, Deserializer};
11-
12-
/// Trims string during deserialization.
13-
pub fn string<'a, D: Deserializer<'a>>(de: D) -> Result<String, D::Error> {
14-
String::deserialize(de).map(|val| val.trim().to_owned())
15-
}
16-
17-
/// Trims string during deserialization, returning error if it ends up empty.
18-
pub fn string_non_empty<'a, D: Deserializer<'a>>(de: D) -> Result<String, D::Error> {
19-
match String::deserialize(de) {
20-
Ok(val) if val.trim().is_empty() => Err(de::Error::invalid_value(
21-
de::Unexpected::Other("empty string"),
22-
&"non-empty string",
23-
)),
24-
Ok(val) => Ok(val.trim().to_owned()),
25-
Err(_) => todo!(),
26-
}
27-
}
28-
29-
/// Trims string during deserialization, returning `None` if it ends up empty.
30-
pub fn option_string_non_empty<'a, D: Deserializer<'a>>(de: D) -> Result<Option<String>, D::Error> {
31-
String::deserialize(de).map(|val| {
32-
Some(val.trim())
33-
.filter(|val| !val.is_empty())
34-
.map(ToOwned::to_owned)
35-
})
36-
}
37-
38-
#[cfg(test)]
39-
mod tests {
40-
use serde::Deserialize;
41-
42-
use super::*;
43-
44-
#[test]
45-
fn string() {
46-
#[derive(Debug, Deserialize, PartialEq, Eq)]
47-
struct Foo {
48-
#[serde(deserialize_with = "crate::string")]
49-
foo: String,
50-
}
51-
52-
impl Foo {
53-
fn new(foo: impl Into<String>) -> Self {
54-
Self { foo: foo.into() }
55-
}
56-
}
57-
58-
assert_eq!(
59-
Foo::new(""),
60-
serde_json::from_str(r#"{ "foo": "" }"#).unwrap(),
61-
);
62-
assert_eq!(
63-
Foo::new(""),
64-
serde_json::from_str(r#"{ "foo": " " }"#).unwrap(),
65-
);
66-
assert_eq!(
67-
Foo::new("bar"),
68-
serde_json::from_str(r#"{ "foo": "bar" }"#).unwrap(),
69-
);
70-
assert_eq!(
71-
Foo::new("bar"),
72-
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
73-
);
74-
assert_eq!(
75-
Foo::new("bar"),
76-
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
77-
);
78-
assert_eq!(
79-
Foo::new("bar"),
80-
serde_json::from_str(r#"{ "foo": "bar " }"#).unwrap(),
81-
);
82-
assert_eq!(
83-
Foo::new("bar"),
84-
serde_json::from_str(r#"{ "foo": " bar " }"#).unwrap(),
85-
);
86-
}
87-
88-
#[test]
89-
fn option_string_non_empty() {
90-
#[derive(Debug, Deserialize, PartialEq, Eq)]
91-
struct Foo {
92-
#[serde(deserialize_with = "crate::option_string_non_empty")]
93-
foo: Option<String>,
94-
}
95-
96-
impl Foo {
97-
fn new(foo: impl Into<String>) -> Self {
98-
Self {
99-
foo: Some(foo.into()),
100-
}
101-
}
102-
103-
fn none() -> Self {
104-
Self { foo: None }
105-
}
106-
}
107-
108-
assert_eq!(
109-
Foo::none(),
110-
serde_json::from_str(r#"{ "foo": "" }"#).unwrap(),
111-
);
112-
assert_eq!(
113-
Foo::none(),
114-
serde_json::from_str(r#"{ "foo": " " }"#).unwrap(),
115-
);
116-
assert_eq!(
117-
Foo::new("bar"),
118-
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
119-
);
120-
assert_eq!(
121-
Foo::new("bar"),
122-
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
123-
);
124-
assert_eq!(
125-
Foo::new("bar"),
126-
serde_json::from_str(r#"{ "foo": "bar " }"#).unwrap(),
127-
);
128-
assert_eq!(
129-
Foo::new("bar"),
130-
serde_json::from_str(r#"{ "foo": " bar " }"#).unwrap(),
131-
);
132-
}
133-
}
11+
pub use crate::{
12+
string::string,
13+
string_non_empty::{option_string_non_empty, string_non_empty},
14+
};

src/string.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use alloc::{borrow::ToOwned as _, string::String};
2+
3+
use serde::{Deserialize as _, Deserializer};
4+
5+
/// Trims string during deserialization.
6+
pub fn string<'a, D: Deserializer<'a>>(de: D) -> Result<String, D::Error> {
7+
String::deserialize(de).map(|val| val.trim().to_owned())
8+
}
9+
10+
#[cfg(test)]
11+
mod tests {
12+
use serde::Deserialize;
13+
14+
use super::*;
15+
16+
#[test]
17+
fn string() {
18+
#[derive(Debug, Deserialize, PartialEq, Eq)]
19+
struct Foo {
20+
#[serde(deserialize_with = "super::string")]
21+
foo: String,
22+
}
23+
24+
impl Foo {
25+
fn new(foo: impl Into<String>) -> Self {
26+
Self { foo: foo.into() }
27+
}
28+
}
29+
30+
serde_json::from_str::<Foo>(r#"{ "foo": 1 }"#).unwrap_err();
31+
serde_json::from_str::<Foo>(r#"{ "foo": bool }"#).unwrap_err();
32+
33+
assert_eq!(
34+
Foo::new(""),
35+
serde_json::from_str(r#"{ "foo": "" }"#).unwrap(),
36+
);
37+
assert_eq!(
38+
Foo::new(""),
39+
serde_json::from_str(r#"{ "foo": " " }"#).unwrap(),
40+
);
41+
assert_eq!(
42+
Foo::new("bar"),
43+
serde_json::from_str(r#"{ "foo": "bar" }"#).unwrap(),
44+
);
45+
assert_eq!(
46+
Foo::new("bar"),
47+
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
48+
);
49+
assert_eq!(
50+
Foo::new("bar"),
51+
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
52+
);
53+
assert_eq!(
54+
Foo::new("bar"),
55+
serde_json::from_str(r#"{ "foo": "bar " }"#).unwrap(),
56+
);
57+
assert_eq!(
58+
Foo::new("bar"),
59+
serde_json::from_str(r#"{ "foo": " bar " }"#).unwrap(),
60+
);
61+
}
62+
}

src/string_non_empty.rs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
use alloc::{borrow::ToOwned, string::String};
2+
3+
use serde::{de, Deserialize as _, Deserializer};
4+
5+
/// Trims string during deserialization, returning error if it ends up empty.
6+
pub fn string_non_empty<'a, D: Deserializer<'a>>(de: D) -> Result<String, D::Error> {
7+
match String::deserialize(de) {
8+
Ok(val) if val.trim().is_empty() => Err(de::Error::invalid_value(
9+
de::Unexpected::Other("empty string"),
10+
&"non-empty string",
11+
)),
12+
Ok(val) => Ok(val.trim().to_owned()),
13+
Err(_) => todo!(),
14+
}
15+
}
16+
17+
/// Trims string during deserialization, returning `None` if it ends up empty.
18+
pub fn option_string_non_empty<'a, D: Deserializer<'a>>(de: D) -> Result<Option<String>, D::Error> {
19+
String::deserialize(de).map(|val| {
20+
Some(val.trim())
21+
.filter(|val| !val.is_empty())
22+
.map(ToOwned::to_owned)
23+
})
24+
}
25+
26+
#[cfg(test)]
27+
mod tests {
28+
use serde::Deserialize;
29+
30+
use super::*;
31+
32+
#[test]
33+
fn string_non_empty() {
34+
#[derive(Debug, Deserialize, PartialEq, Eq)]
35+
struct Foo {
36+
#[serde(deserialize_with = "super::string_non_empty")]
37+
foo: String,
38+
}
39+
40+
impl Foo {
41+
fn new(foo: impl Into<String>) -> Self {
42+
Self { foo: foo.into() }
43+
}
44+
}
45+
46+
serde_json::from_str::<Foo>(r#"{ "foo": "" }"#).unwrap_err();
47+
serde_json::from_str::<Foo>(r#"{ "foo": " " }"#).unwrap_err();
48+
49+
assert_eq!(
50+
Foo::new("bar"),
51+
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
52+
);
53+
assert_eq!(
54+
Foo::new("bar"),
55+
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
56+
);
57+
assert_eq!(
58+
Foo::new("bar"),
59+
serde_json::from_str(r#"{ "foo": "bar " }"#).unwrap(),
60+
);
61+
assert_eq!(
62+
Foo::new("bar"),
63+
serde_json::from_str(r#"{ "foo": " bar " }"#).unwrap(),
64+
);
65+
}
66+
67+
#[test]
68+
fn option_string_non_empty() {
69+
#[derive(Debug, Deserialize, PartialEq, Eq)]
70+
struct Foo {
71+
#[serde(deserialize_with = "super::option_string_non_empty")]
72+
foo: Option<String>,
73+
}
74+
75+
impl Foo {
76+
fn new(foo: impl Into<String>) -> Self {
77+
Self {
78+
foo: Some(foo.into()),
79+
}
80+
}
81+
82+
fn none() -> Self {
83+
Self { foo: None }
84+
}
85+
}
86+
87+
assert_eq!(
88+
Foo::none(),
89+
serde_json::from_str(r#"{ "foo": "" }"#).unwrap(),
90+
);
91+
assert_eq!(
92+
Foo::none(),
93+
serde_json::from_str(r#"{ "foo": " " }"#).unwrap(),
94+
);
95+
assert_eq!(
96+
Foo::new("bar"),
97+
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
98+
);
99+
assert_eq!(
100+
Foo::new("bar"),
101+
serde_json::from_str(r#"{ "foo": " bar" }"#).unwrap(),
102+
);
103+
assert_eq!(
104+
Foo::new("bar"),
105+
serde_json::from_str(r#"{ "foo": "bar " }"#).unwrap(),
106+
);
107+
assert_eq!(
108+
Foo::new("bar"),
109+
serde_json::from_str(r#"{ "foo": " bar " }"#).unwrap(),
110+
);
111+
}
112+
}

0 commit comments

Comments
 (0)