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

Consider making the fields of Spanned public #368

Open
Kixunil opened this issue Nov 9, 2022 · 5 comments
Open

Consider making the fields of Spanned public #368

Kixunil opened this issue Nov 9, 2022 · 5 comments
Labels
A-serde Area: Serde integration C-enhancement Category: Raise on the bar on expectations

Comments

@Kixunil
Copy link

Kixunil commented Nov 9, 2022

I think Spanned should be just a POD with all its fields public or at least the value field should be. Not being public makes matching extra annoying.

My use case: I have a toml that allows setting one of two fields only if another is either not set or set to false (they are contradictory) so I deserialize both fields and then I match on the tuple of them emitting an error if an invalid combination is present (and convert to a proper enum a valid one is). I'd love to make the error message look as nice as Rust error messages - having "foo specified here" and "bar specified here" messages pointing at the places where they are specified. I need span for this so I'm refactoring the match.

@epage
Copy link
Member

epage commented Nov 10, 2022

The only relevant issue I found in the old toml-rs repo was toml-rs/toml-rs#436

I generally lean towards types being all pub or all private. My main concern over exposing Spanneds fields is if we'd want to use an actual range type so we can clarify the bounds via the type system.

I wonder what the rest of the ecosystem does.

@epage epage added the A-parse Area: Parsing TOML label Nov 10, 2022
@Kixunil
Copy link
Author

Kixunil commented Nov 10, 2022

To add to your list codespan-reporting uses range. Which I personally don't like much - semantically encoding "this is a span not some arbitrary range" is nice.

In my own crate I wrote struct Span { start: usize, end: usize } and conversions between toml and codespan-reporting types.

@epage epage added C-enhancement Category: Raise on the bar on expectations A-serde Area: Serde integration and removed A-parse Area: Parsing TOML labels Jan 18, 2023
@dtolnay
Copy link
Contributor

dtolnay commented Dec 19, 2023

I opened #664 to try to make progress by exposing a way to construct Spanned, even if the fields aren't public.

I would be happy for us to consider Spanned::new(lo..hi, value) or Spanned::new(value).with_range(lo..hi), the latter not precluding construction with a better span type in the future if we settle on one.

@epage
Copy link
Member

epage commented Dec 19, 2023

for that use case, would #634 be more relevant? We have a prototype at #635 that is just waiting on feedback

@dtolnay
Copy link
Contributor

dtolnay commented Dec 19, 2023

As I understand it, #635 adds a mechanism by which authors of a Deserializer impl can look at a particular deserialize_struct call and tell whether Spanned<T> is the thing being deserialized, and if so, feed it with the right range for Spanned<T> to get deserialized successfully.

That is not the missing piece in dtolnay/serde-untagged#5. Serde-untagged implements a particularly clever Visitor, which the caller uses for implementing Deserialize. There is no Deserializer impl at play in that crate.

The only way that I see SpannedDeserializer could come into play is if serde-untagged did either of these 2 things:

  1. If it deserialized the entire input into Spanned<Buffer> first. Then allowed the user's functions to deserialize Spanned<T> from serde-untagged's buffer: .map(|map| map.deserialize::<Spanned<TomlDetailedDependency>>()). For this it would need SpannedDeserializer in implementing the Buffer type's Deserializer impl.

  2. If it had a Deserializer adapter that wrapped the incoming Deserializer provided by the caller to .deserialize(deserializer), and intercepted the deserialize_struct call there without buffering, and behaved differently based on whether it is or isn't Spanned that the caller wants to deserialize.

But:

  1. The point of that crate is to have no buffering, due to Internal buffering disrupts format-specific deserialization features serde-rs/serde#1183.

  2. This would not be useful because without buffering, it would only be able to support at most 1 Spanned case in your untagged enum. You would not be able to have 2 or more variants which are both Spanned, which is what the issue in serde-untagged is in need of, I think.

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-enhancement Category: Raise on the bar on expectations
Projects
None yet
Development

No branches or pull requests

3 participants