Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Newtype as the key of a HashMap/BTreeMap is not supported #586

Closed
TonalidadeHidrica opened this issue Jul 25, 2023 · 2 comments · Fixed by #612
Closed

Newtype as the key of a HashMap/BTreeMap is not supported #586

TonalidadeHidrica opened this issue Jul 25, 2023 · 2 comments · Fixed by #612
Labels
A-serde Area: Serde integration C-bug Category: Things not working as expected

Comments

@TonalidadeHidrica
Copy link

A newtype - a named single-tuple type - cannot be used as the key of a HashMap or a BTreeMap.

playground

use std::collections::HashMap;
use serde::Deserialize;

#[derive(PartialEq, Eq, Hash, Debug, Deserialize)]
struct NewType(String);

fn main() -> anyhow::Result<()> {
    let map = toml::from_str::<HashMap<NewType, u32>>(r#"
    x = 1
    y = 2
    "#)?;
    println!("{map:?}");
    Ok(())
}
Error: TOML parse error at line 2, column 5
  |
2 |     x = 1
  |     ^
invalid type: string "x", expected tuple struct NewType

This is contrary to serde_json.

playground

use std::collections::HashMap;
use serde::Deserialize;

#[derive(PartialEq, Eq, Hash, Debug, Deserialize)]
struct NewType(String);

fn main() -> anyhow::Result<()> {
    let map = serde_json::from_str::<HashMap<NewType, u32>>(r#"
    {"x": 1, "y": 2}
    "#)?;
    println!("{map:?}");
    Ok(())
}
{NewType("x"): 1, NewType("y"): 2}

I ran into this issue in my project, and I think that this should definitely be supported.

@epage epage added C-bug Category: Things not working as expected A-serde Area: Serde integration labels Jul 28, 2023
@m4tx
Copy link

m4tx commented Sep 26, 2023

Ran into the same issue today.

@m4tx
Copy link

m4tx commented Sep 26, 2023

Actually - this might be somewhat expected, as NewType does not seem to support deserialization from &str by default.

The solution is to modify the newtype so that it behaves just like the underlying type:

#[derive(PartialEq, Eq, Hash, Debug, Deserialize)]
#[serde(transparent)]
struct NewType(String);

With the addition of #[serde(transparent)], the code posted in the issue seems to be working just fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-serde Area: Serde integration C-bug Category: Things not working as expected
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants