Skip to content

[3/n] allow JSON schemas relative to the out dir#1301

Open
sunshowers wants to merge 4 commits intomainfrom
sunshowers/spr/3n-allow-json-schemas-relative-to-the-out-dir
Open

[3/n] allow JSON schemas relative to the out dir#1301
sunshowers wants to merge 4 commits intomainfrom
sunshowers/spr/3n-allow-json-schemas-relative-to-the-out-dir

Conversation

@sunshowers
Copy link
Contributor

In upcoming work related to RFD 634 we're going to need to read JSON files out of the build script output directory. Add support for that.

Created using spr 1.3.6-beta.1

[skip ci]
Created using spr 1.3.6-beta.1
Created using spr 1.3.6-beta.1
/// The path to the spec file.
path: LitStr,
/// Where to resolve the path relative to.
relative_to: RelativeTo,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be #[serde(default)] and should RelativeTo derive Default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe? That's what I had at first, but I figured if you're using the struct style in the first place, you're probably intending to specify relative_to.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I was thrown off by a description of a default variant of RelativeTo

relative_to: RelativeTo,
}

impl SpecSource {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be impl syn::Parse for SpecSource?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting idea, and definitely better than what I did. I keep forgetting how syn works, haha. Might be worth putting this pattern somewhere in a list of serde_tokenstream recipes.

Changed it to this + lookahead1 as commented below. I did a bunch of testing on span attributions, and the big thing is that you cannot have the MacroSettings struct use ParseWrapper<SpecSource> directly. Instead, it must be a TokenStreamWrapper that is later parsed.

(related, we don't have a directory of failing inputs to test span attributions for progenitor with -- is it worth building that?)

Comment on lines 15 to 24
openapiv3 = "2.2.0"
proc-macro2 = "1.0"
progenitor-impl = { version = "0.12.0", path = "../progenitor-impl" }
quote = "1.0"
schemars = "0.8.22"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"
serde_tokenstream = "0.2.0"
serde_tokenstream = "0.2.2"
syn = { version = "2.0", features = ["full", "extra-traits"] }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems like all/most of these should be { workspace = true }. I'm not sure why they're not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah they should. Should I do this as a followup?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either way; I'm happy to do it myself later

@sunshowers sunshowers changed the base branch from sunshowers/spr/main.3n-allow-json-schemas-relative-to-the-out-dir to main February 7, 2026 21:21
Created using spr 1.3.6-beta.1
Comment on lines +189 to +190
// Note this is a TokenStreamWrapper and not a ParseWrapper<SpecSource>. The
// latter loses span information.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. is that an intrinsic property of ParseWrapper or is it fixable?
  2. How much do we care? We use ParseWrapper in several other places.

Copy link
Contributor Author

@sunshowers sunshowers Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an artifact of the D::Error::custom being called here: https://docs.rs/serde_tokenstream/latest/src/serde_tokenstream/ibidem.rs.html#59 -- serde flattens custom errors into their Display implementation, so that loses span information. The span used ends up being the span of the entire value associated with the key (so for spec, the entire { path = ..., relative_to = ... }).

Can this be fixed? Maybe we could use a side channel similar to the WRAPPER_TOKENS thread local in ibidem.rs. Worth investigating.

This probably doesn't matter for scalars like ParseWrapper<syn::Ident>. It only matters for compound structures like SpecSource. But I see that we have:

    pre_hook: Option<ParseWrapper<ClosureOrPath>>,
    pre_hook_async: Option<ParseWrapper<ClosureOrPath>>,
    post_hook: Option<ParseWrapper<ClosureOrPath>>,
    post_hook_async: Option<ParseWrapper<ClosureOrPath>>,

which would all be impacted.

Copy link
Contributor Author

@sunshowers sunshowers Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oxidecomputer/serde_tokenstream#221 fixes this. Once that lands and a new serde_tokenstream version is out, we can change this code to use ParseWrapper directly. (Note that ParseWrapper isn't totally compatible with the error collector/diagnostic sink proc macro pattern where we collect all errors into a common place, but that is a pre-existing limitation.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants