Skip to content

Commit 1eef6c9

Browse files
authored
feat: add optional jiff 0.2 shape support (#19)
1 parent 2f91767 commit 1eef6c9

8 files changed

Lines changed: 199 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ jobs:
103103
- name: Check no_std
104104
run: |
105105
cargo check -p serde-shape --lib --no-default-features --target thumbv7em-none-eabihf
106+
cargo check -p serde-shape --lib --no-default-features --features jiff02 --target thumbv7em-none-eabihf
106107
cargo check -p serde-shape-test-no-std --lib --target thumbv7em-none-eabihf
107108
shell: bash
108109

Cargo.lock

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

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ Types that branch on `Serializer::is_human_readable()` or `Deserializer::is_huma
188188
`serde-shape` enables no features by default.
189189

190190
- `derive`: enables `#[derive(SerializeShape)]` and `#[derive(DeserializeShape)]`.
191+
- `jiff02`: enables string shapes for Jiff 0.2 types with direct Serde implementations.
191192
- `std`: enables shape implementations for standard-library-only types.
192193

193194
## Built-in shapes
@@ -205,6 +206,8 @@ The built-in implementations follow Serde's semantic representations in each dir
205206
| Network | `core::net` IP and socket address types |
206207
| `std` feature | Atomics available on the target, `HashMap`, `HashSet`, `Path`, `PathBuf`, `Mutex`, and `RwLock` |
207208

209+
With the `jiff02` feature, `Date`, `DateTime`, `ISOWeekDate`, `SignedDuration`, `Span`, `Time`, `Timestamp`, and `Zoned` are string shapes in both directions, matching Jiff's direct Serde implementations.
210+
208211
Network address shapes are unions of their human-readable string representation and their compact Serde representation. A serialized byte slice and an owned `Box<[u8]>` input are sequences, while borrowed byte deserialization uses `ShapeRef::Bytes`.
209212

210213
OS string shapes preserve Serde's target-specific externally tagged representation: `Unix` contains a byte sequence, while `Windows` contains a `u16` sequence. Deserialization advertises only the variant accepted on the current target.

serde-shape/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ rustdoc-args = ["--cfg", "docsrs"]
3535
[features]
3636
default = []
3737
derive = ["dep:serde-shape-derive"]
38+
jiff02 = ["dep:jiff02"]
3839
std = []
3940

4041
[dependencies]
42+
jiff02 = { package = "jiff", version = "0.2", default-features = false, optional = true }
4143
serde-shape-derive = { workspace = true, optional = true }
4244

4345
[lints]

serde-shape/src/impls/jiff02.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2026 FastLabs Developers
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use jiff02::SignedDuration;
16+
use jiff02::Span;
17+
use jiff02::Timestamp;
18+
use jiff02::Zoned;
19+
use jiff02::civil::Date;
20+
use jiff02::civil::DateTime;
21+
use jiff02::civil::ISOWeekDate;
22+
use jiff02::civil::Time;
23+
24+
use crate::DeserializeShape;
25+
use crate::DeserializeShapeContext;
26+
use crate::SerializeShape;
27+
use crate::SerializeShapeContext;
28+
use crate::ShapeRef;
29+
30+
macro_rules! string_shape {
31+
($($ty:ty),* $(,)?) => {
32+
$(
33+
impl SerializeShape for $ty {
34+
fn serialize_shape_in(_context: &mut SerializeShapeContext) -> ShapeRef {
35+
ShapeRef::String
36+
}
37+
}
38+
39+
impl DeserializeShape for $ty {
40+
fn deserialize_shape_in(_context: &mut DeserializeShapeContext) -> ShapeRef {
41+
ShapeRef::String
42+
}
43+
}
44+
)*
45+
};
46+
}
47+
48+
string_shape!(
49+
Date,
50+
DateTime,
51+
ISOWeekDate,
52+
SignedDuration,
53+
Span,
54+
Time,
55+
Timestamp,
56+
Zoned,
57+
);

serde-shape/src/impls/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
mod bound;
1616
mod container;
1717
mod ffi;
18+
#[cfg(feature = "jiff02")]
19+
mod jiff02;
1820
mod net;
1921
#[cfg(all(feature = "std", any(unix, windows)))]
2022
mod os_string;

serde-shape/src/tests.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,30 @@ fn maps_network_shapes_without_std() {
645645
FieldWireShape::Value(ShapeRef::Tuple(vec![ipv4_binary, ShapeRef::U16]))
646646
);
647647
}
648+
649+
#[cfg(feature = "jiff02")]
650+
#[test]
651+
fn maps_jiff_serde_types_to_strings() {
652+
fn assert_string_shapes<T>()
653+
where
654+
T: DeserializeShape + SerializeShape,
655+
{
656+
assert_eq!(
657+
DeserializeShapeGraph::for_type::<T>().root(),
658+
&ShapeRef::String
659+
);
660+
assert_eq!(
661+
SerializeShapeGraph::for_type::<T>().root(),
662+
&ShapeRef::String
663+
);
664+
}
665+
666+
assert_string_shapes::<jiff02::civil::Date>();
667+
assert_string_shapes::<jiff02::civil::DateTime>();
668+
assert_string_shapes::<jiff02::civil::ISOWeekDate>();
669+
assert_string_shapes::<jiff02::civil::Time>();
670+
assert_string_shapes::<jiff02::SignedDuration>();
671+
assert_string_shapes::<jiff02::Span>();
672+
assert_string_shapes::<jiff02::Timestamp>();
673+
assert_string_shapes::<jiff02::Zoned>();
674+
}

xtask/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ impl CommandTest {
8787
run_command(make_test_cmd(self.no_capture, "serde-shape", &[]));
8888
run_command(make_test_cmd(self.no_capture, "serde-shape", &["std"]));
8989
run_command(make_test_cmd(self.no_capture, "serde-shape", &["derive"]));
90+
run_command(make_test_cmd(self.no_capture, "serde-shape", &["jiff02"]));
9091
run_command(make_test_cmd(
9192
self.no_capture,
9293
"serde-shape",

0 commit comments

Comments
 (0)