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

span and capturing additional fields #526

Closed
User65k opened this issue Mar 13, 2023 · 4 comments
Closed

span and capturing additional fields #526

User65k opened this issue Mar 13, 2023 · 4 comments
Labels
A-serde Area: Serde integration C-bug Category: Things not working as expected

Comments

@User65k
Copy link

User65k commented Mar 13, 2023

I have to capture additional fields when deserializing.

Unfortunately, this is messing up the nice error messages / span info.
It always points to the first line.

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

#[derive(Deserialize, Debug)]
struct Outer {
    item: u8,
    #[serde(flatten)]
    rest: HashMap<String, u8>,
}
pub fn main(){    
        let t_str = r#"#a bit of content
item = 7
i = false
"#;
        let res: Result<Outer, toml::de::Error> = toml::from_str(t_str);
        let got = res.unwrap_err();
        println!("{}", got);
}
TOML parse error at line 1, column 1
  |
1 | #a bit of content
  | ^^^^^^^^^^^^^^^^^
invalid type: boolean `false`, expected u8

Playground link with tests: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ca33eb1e091fb94d4313f361022c2208

@epage
Copy link
Member

epage commented Mar 13, 2023

The call stack for an error during flatten looks something like

0: toml_edit::parser::errors::TomlError::custom                                                                                   [1187/4759]
          at /home/epage/src/personal/toml/crates/toml_edit/src/parser/errors.rs:52:24                                                       1: toml_edit::de::Error::custom                                                                                                                        at /home/epage/src/personal/toml/crates/toml_edit/src/de/mod.rs:36:20                                                              2: <toml_edit::de::Error as serde::de::Error>::custom                                                                                                  at /home/epage/src/personal/toml/crates/toml_edit/src/de/mod.rs:65:9
   serde::de::Error::invalid_type
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/mod.rs:209:17
3: serde::__private::de::content::ContentRefDeserializer<E>::invalid_type
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/private/de.rs:1750:13
4: serde::__private::de::content::ContentRefDeserializer<E>::deserialize_integer
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/private/de.rs:1766:26
   <serde::__private::de::content::ContentRefDeserializer<E> as serde::de::Deserializer>::deserialize_u8
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/private/de.rs:1907:13
5: serde::de::impls::<impl serde::de::Deserialize for u8>::deserialize
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/impls.rs:129:17
   <core::marker::PhantomData<T> as serde::de::DeserializeSeed>::deserialize
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/mod.rs:791:9
   <serde::__private::de::FlatMapAccess<E> as serde::de::MapAccess>::next_value_seed
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/private/de.rs:2886:28
   serde::de::MapAccess::next_entry_seed
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/mod.rs:1836:34
   serde::de::MapAccess::next_entry
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/mod.rs:1884:9
   <serde::de::impls::<impl serde::de::Deserialize for std::collections::hash::map::HashMap<K,V,S>>::deserialize::MapVisitor<K,V,S> as serde::de::Visitor>::visit_map
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/impls.rs:1393:61
   <serde::__private::de::FlatMapDeserializer<E> as serde::de::Deserializer>::deserialize_map
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/private/de.rs:2775:9
6: serde::de::impls::<impl serde::de::Deserialize for std::collections::hash::map::HashMap<K,V,S>>::deserialize
          at /home/epage/.cargo/registry/src/github.aaakk.us.kg-1ecc6299db9ec823/serde-1.0.152/src/de/impls.rs:1402:17
   <testsuite::de_errors::flatten_has_valid_span::_::<impl serde::de::Deserialize for testsuite::de_errors::flatten_has_valid_span::Flatten>::deserialize::__Visitor as serde::de::Visitor>::visit_map
          at tests/testsuite/de_errors.rs:487:14
   <toml_edit::de::table::TableDeserializer as serde::de::Deserializer>::deserialize_any
          at /home/epage/src/personal/toml/crates/toml_edit/src/de/table.rs:21:9
7: <toml_edit::de::value::ValueDeserializer as serde::de::Deserializer>::deserialize_any
          at /home/epage/src/personal/toml/crates/toml_edit/src/de/value.rs:75:38
8: <toml_edit::de::Deserializer as serde::de::Deserializer>::deserialize_any

@epage
Copy link
Member

epage commented Mar 13, 2023

Normally you would expect the key/value processing to be in a call stack like this which is what could set the span. I suspect for flattens, serde is capturing what we deserialize and then replaying that, removing us from the call stack to set a more specific span.

So we set a span for the whole table with the problem but we aren't rendering multi-line spans correctly (#458)

@epage
Copy link
Member

epage commented Mar 13, 2023

btw I have this written out as a test case

#[test]
fn flatten_has_valid_span() {
    #[derive(Deserialize, Debug)]
    struct Unflatten {
        #[allow(dead_code)]
        item: u8,
        #[allow(dead_code)]
        i: u8,
    }
    bad!(
        r#"#a bit of content
item = 7
i = false
"#,
        Unflatten,
        "\
TOML parse error at line 3, column 5
  |
3 | i = false
  |     ^^^^^
invalid type: boolean `false`, expected u8
"
    );
    #[derive(Deserialize, Debug)]
    struct Flatten {
        #[allow(dead_code)]
        item: u8,
        #[allow(dead_code)]
        #[serde(flatten)]
        rest: std::collections::HashMap<String, u8>,
    }
    bad!(
        r#"#a bit of content
item = 7
i = false
"#,
        Flatten,
        "\
TOML parse error at line 3, column 5
  |
3 | i = false
  |     ^^^^^
invalid type: boolean `false`, expected u8
"
    );
}

@epage epage added C-bug Category: Things not working as expected A-serde Area: Serde integration labels Mar 8, 2024
@epage
Copy link
Member

epage commented Mar 8, 2024

Closing in favor of #589

@epage epage closed this as not planned Won't fix, can't repro, duplicate, stale Mar 8, 2024
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

No branches or pull requests

2 participants