Skip to content

Commit f80db01

Browse files
committed
Add readme and some documentation
1 parent bef23e9 commit f80db01

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
[package]
22
name = "serde_flat_path"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
authors = ["Jasper Meggitt <[email protected]>"]
55
description = "A macro for expanding long structure chains within serde"
66
license = "MIT"
77
edition = "2021"
88
repository = "https://github.com/jmeggitt/serde_flat_path"
99
keywords = ["serde", "flatten"]
10+
readme = "readme.md"
1011

1112
[lib]
1213
proc-macro = true

readme.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# `serde_flat_path`
2+
This crate was designed to solve the problem of needing to manually create placeholder structs or untyped values (such
3+
as `serde_json::Value`). For example, take this json file:
4+
```json
5+
{
6+
"title": "Foo",
7+
"foo": true,
8+
"config": {
9+
"bar": {
10+
"name": "foo bar"
11+
}
12+
}
13+
}
14+
```
15+
Using serde derive, you would likely arrive at something similar to the code shown below. As you can see, you may need
16+
to create separate structures for `config` and `bar` despite only containing a single field of interest each.
17+
```rust
18+
#[derive(Deserialize)]
19+
struct Foo {
20+
title: String,
21+
foo: bool,
22+
config: FooConfig,
23+
}
24+
25+
#[derive(Deserialize)]
26+
struct FooConfig {
27+
bar: Bar,
28+
}
29+
30+
#[derive(Deserialize)]
31+
struct Bar {
32+
name: String,
33+
}
34+
```
35+
To solve this problem, this crate provides a macro for shortening a long path to a single field.
36+
```rust
37+
#[flat_path]
38+
#[derive(Deserialize)]
39+
struct Foo {
40+
title: String,
41+
foo: bool,
42+
#[flat_path("config.bar.name")]
43+
bar_name: String,
44+
}
45+
```
46+
47+
## Usage
48+
`flat_path` can be applied to any named field within a `struct` or `enum`. The `#[flat_path]` attribute must be applied
49+
before the serialize/deserialize `#[derive(...)]` so that it can apply the necessary serde attributes before serde
50+
performs macro expansion for its derive macros. Similar to derive macros, the original type is not altered.
51+
52+
For cases where field names contain `.` or additional verbosity is desired, `#[flat_path("a.b.c")]` may also be written
53+
as `#[flat_path(path = ["a", "b", "c"])]`. These two forms are equivalent and no distinction is made between regarding
54+
macro expansion.
55+
56+
`#[serde(...)]` attributes are also moved from `#[flat_path(...)]` fields to the final field within the path. During
57+
this process, the order of attributes remains the same.
58+

src/lib.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,32 @@
1+
//! `flat_path` can be applied to any named field within a `struct` or `enum`. The `#[flat_path]`
2+
//! attribute must be applied before the serialize/deserialize `#[derive(...)]` so that it can apply
3+
//! the necessary serde attributes before serde performs macro expansion for its derive macros.
4+
//! Similar to derive macros, the original type is not altered.
5+
//!
6+
//! For cases where field names contain `.` or additional verbosity is desired,
7+
//! `#[flat_path("a.b.c")]` may also be written as `#[flat_path(path = ["a", "b", "c"])]`. These two
8+
//! forms are equivalent and no distinction is made between regarding macro expansion.
9+
//!
10+
//! `#[serde(...)]` attributes are also moved from `#[flat_path(...)]` fields to the final field
11+
//! within the path. During this process, the order of attributes remains the same.
12+
//!
13+
//! ```rust
14+
//! # use serde::{Serialize, Deserialize};
15+
//! # use serde_flat_path::flat_path;
16+
//! #[flat_path]
17+
//! #[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Default)]
18+
//! #[serde(default)]
19+
//! pub struct Foo {
20+
//! foo: bool,
21+
//! #[flat_path(path=["a", "b", "c"])]
22+
//! x: Option<u64>,
23+
//! #[serde(rename="INDEX")]
24+
//! index_number: u32,
25+
//! }
26+
//! ```
27+
//!
28+
//! For more examples see the repository's tests folder.
29+
130
use proc_macro::TokenStream;
231
use proc_macro2::Span;
332
use proc_macro2::{Ident, TokenStream as TokenStream2};
@@ -9,8 +38,10 @@ use syn::{
938
};
1039

1140
mod attr;
41+
1242
use attr::*;
1343

44+
/// For documentation go to the [crate] root page.
1445
#[proc_macro_attribute]
1546
pub fn flat_path(attr: TokenStream, input: TokenStream) -> TokenStream {
1647
match flat_path_impl(attr, input) {

0 commit comments

Comments
 (0)