https://github.com/messense/serde-single-key-map
Unwrap a single key map with serde
https://github.com/messense/serde-single-key-map
serde
Last synced: about 1 year ago
JSON representation
Unwrap a single key map with serde
- Host: GitHub
- URL: https://github.com/messense/serde-single-key-map
- Owner: messense
- License: mit
- Created: 2019-12-13T07:34:15.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-12-13T12:23:43.000Z (over 6 years ago)
- Last Synced: 2025-04-23T02:16:02.976Z (about 1 year ago)
- Topics: serde
- Language: Rust
- Size: 4.88 KB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# serde-single-key-map
[](https://github.com/messense/serde-single-key-map/actions?query=workflow%3ACI)
[](https://crates.io/crates/serde-single-key-map)
[](https://docs.rs/serde-single-key-map/)
Unwrap a single key map with serde.
## Installation
Add it to your `Cargo.toml`:
```toml
[dependencies]
serde-single-key-map = "0.1"
```
## Usage
```rust
#[derive(Debug, Deserialize)]
struct Project {
name: String,
#[serde(deserialize_with = "serde_single_key_map::deserialize")]
items: Vec,
}
#[derive(Debug, Deserialize)]
struct Item {
name: String,
source: String,
}
fn main() {
let s = r#"{
"name": "test",
"items": {
"item": [
{
"name": "name",
"source": "name.rs"
}
]
}
}"#;
let project: Project = serde_json::from_str(s).expect("deserialize failed");
assert_eq!(project.name, "test");
assert_eq!(project.items.len(), 1);
let item = &project.items[0];
assert_eq!(item.name, "name");
assert_eq!(item.source, "name.rs");
}
```
## Motivation
The primary use case for this crate is to remove a unnessery intermediary struct when deserializing. For example, consider the following XML:
```xml
key1
value1
key2
value2
```
There is only one `TagSet` element in `GetBucketTaggingOutput`, so naturally you'd write the following code to represent it:
```rust
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct GetBucketTaggingOutput {
#[serde(rename = "TagSet")]
pub tag_set: Vec,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct Tag {
/// Name of the tag.
#[serde(rename = "Key")]
pub key: String,
/// Value of the tag.
#[serde(rename = "Value")]
pub value: String,
}
```
But it won't work, you'd have to add a intermediary `TagSet` struct to make it work:
```rust
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct GetBucketTaggingOutput {
#[serde(rename = "TagSet")]
tag_set: TagSet,
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct TagSet {
#[serde(rename = "Tag")]
tags: Vec,
}
```
with `serde-single-key-map` you can make it work with a single line of change:
```diff
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct GetBucketTaggingOutput {
+ #[serde(deserialize_with = "serde_single_key_map::deserialize")]
#[serde(rename = "TagSet")]
pub tag_set: Vec,
}
```
## License
This work is released under the MIT license. A copy of the license is provided in the [LICENSE](./LICENSE) file.