The surface owns generation: no generator file, no wrapper crate - #11
Open
zmaril wants to merge 1 commit into
Open
The surface owns generation: no generator file, no wrapper crate#11zmaril wants to merge 1 commit into
zmaril wants to merge 1 commit into
Conversation
The owner did not like the binding setup: annotating should feel like `pub`, on
the original function, with no special files. Two things stood in the way, and
both were jedem's.
A consumer had to write a generator bin. Now `surface!` takes an optional
`bindings:` directory and emits the generation itself, as a test:
jedem::surface! {
name: "hello", version: "0.1.0",
api: [Hello, fallible, ripeness],
bindings: "bindings",
}
`cargo test` checks the committed bindings; `JEDEM_WRITE=1 cargo test` rewrites
them, and `cargo jedem generate` does the same thing under a nicer name. Writing
is opt-in so an ordinary test run is a check and never a silent rewrite -- the
shape every snapshot-testing tool uses. That removes the last hand-written file:
no bin, and no drift-guard test to write either, since the emitted one is the
guard.
The generated manifests keyed their dependency on the RUST CRATE name, so a
package whose name contains a hyphen produced a manifest cargo could not
resolve. jawohl hit this and worked around it by renaming its package; jedem's
own demo never could, because `hello` has no hyphen. Manifests now key on the
package name and generated code uses the crate name, which are separate inputs.
The demo is converted to prove both rather than assert them: its generator bin
and its drift-guard test are deleted, the binding crates move under
demo/hello/bindings/ where the surface points, and the guard is verified to fire
-- changing one doc comment fails the test with the regeneration command.
Also, generated code is no longer formatted. rustfmt rewraps method chains that
exceed its chain_width, which jedem cannot predict, so `cargo fmt --all` made
committed bindings differ from a fresh generation. Formatting generated code is
the wrong operation on it; a rustfmt.toml records the rule and CI formats only
the hand-written crates.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HsDxLrGdx6nPaXkVEWkNvS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You said annotating should feel like
pub— on the original function, nospecial files. Two things stood in the way, and both were jedem's.
No generator file
surface!now takes an optionalbindings:directory and emits generationitself:
cargo test— checks the committed bindingsJEDEM_WRITE=1 cargo test— rewrites themcargo jedem generate— the same, under a nicer nameWriting is opt-in, so an ordinary test run is a check and never a silent
rewrite — the shape every snapshot tool uses. That removes the last
hand-written file: no generator bin, and no drift-guard test either, because
the emitted one is the guard.
The manifest-key bug jawohl hit
Generated manifests keyed their dependency on the Rust crate name, so a
package named
jawohl-surfaceproduced a manifest cargo could not resolve.jawohl worked around it by renaming its package; jedem's own demo could never
catch it, because
hellohas no hyphen.Manifests now key on the package name while generated code uses the crate
name — they are separate inputs, and conflating them only looked fine because
the demo had no hyphen.
Proven, not asserted
The demo's generator bin and drift-guard test are deleted, its binding
crates move under
demo/hello/bindings/, and the guard is verified to fire:changing one doc comment fails with
Both host round-trips still pass.
Generated code is not formatted
rustfmt rewraps method chains exceeding its
chain_width, which jedem cannotpredict, so
cargo fmt --allmade committed bindings differ from a freshgeneration. Formatting generated code is the wrong operation on it — you
regenerate it. A
rustfmt.tomlrecords the rule; CI formats only hand-writtencrates.
40 tests, clippy clean.
Next, in jawohl: annotate
complete_json,SyntaxandValidationdirectly, add the one-shot functions as real public API, and delete the surface
crate entirely. That needs jawohl to depend on jedem — see my note on the PR.
🤖 Generated with Claude Code
https://claude.ai/code/session_01HsDxLrGdx6nPaXkVEWkNvS