1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
//! # prebindgen-registry
//!
//! Registry-based, **language-agnostic** converter pipeline for
//! [`prebindgen`](https://docs.rs/prebindgen). This crate turns a stream of
//! `#[prebindgen]` items — read through [`Source`](::prebindgen::Source) and
//! parsed by [`flat::Flat`] — into generated Rust FFI bindings plus a fully
//! resolved table of type converters. It has no knowledge of any particular
//! destination language — C, JNI/Kotlin, Swift, Python, etc. all plug in the
//! same way.
//!
//! It also re-exports the flat model (`flat`, `shape`, `types_util`) from
//! the separate [`prebindgen-flat`](https://docs.rs/prebindgen-flat) crate, so
//! a language adapter names one crate root for the whole pipeline rather than
//! reaching back into `prebindgen-flat` for half of it.
//!
//! # The plug-in point
//!
//! Write one generator per destination language. It does two things:
//!
//! * **Says how the language represents Rust types on the wire** — it builds a
//! [`ConverterImpl`] (a generated converter fn plus its wire type) for each
//! crossing the registry hands it, and gives them all back through
//! `RegistryBuilder::convert_with`.
//! * **Emits the wrapper code per item** — `on_function` / `on_struct` /
//! `on_enum` / `on_const` on the [`Prebindgen`] trait.
//!
//! Everything language-specific that must travel through the pipeline rides in
//! the back-end's chosen [`Metadata`](Prebindgen::Metadata) type (a JNI
//! back-end's Kotlin class names and exception info, a C back-end's header
//! names, …). It is set on each converter, propagated into the registry's
//! [`TypeEntry`], and read back by the back-end's own emitter — no side
//! channels. Back-ends needing no extras leave it at the default `()`.
//!
//! # Flow
//!
//! A build script sees one type — the generator — and never names a `Flat` or a
//! `Registry`:
//!
//! ```ignore
//! let jni = JniGen::builder()
//! .package(package!("io.zenoh"))
//! .fun(fun!(session_open))
//! .source(zenoh_flat::PREBINDGEN_OUT_DIR)
//! .build()?;
//! jni.write_rust(&rust_dest)?;
//! jni.write_kotlin(&kotlin_root)?;
//! ```
//!
//! Inside `build()`, the generator does what it alone knows how to do:
//!
//! 1. [`flat::Flat::builder`] parses the declared sources into the model, and
//! [`Registry::builder`] starts describing a binding over it.
//! 2. The generator states that binding, then [`RegistryBuilder::crossings`]
//! hands over every crossing needing a conversion — inner types first, so
//! each one can be built from those already done. `convert_with` answers
//! them and `build` names any gap.
//! 3. The resolved registry becomes a field of the built generator, whose
//! `write_*` methods emit the artifacts — Rust wrappers, and whatever else
//! that language needs (a C header, Kotlin sources, …).
//!
//! # Universality, by example
//!
//! The same machinery serves very different languages:
//!
//! * **C / cbindgen back-end** (the separate `prebindgen-c` crate): wire types
//! are raw pointers and primitive C types; converters are thin transmutes;
//! `pre_stages` are usually empty (errors surface as return codes).
//! * **JNI / Kotlin back-end** (the separate `prebindgen-jni` crate): wire
//! types are JNI handles (`jlong`, `JObject`); converters marshal across the
//! JVM boundary; `pre_stages` carry fallible steps whose `Err` arms throw
//! JVM exceptions (the exception info lives in that back-end's `Metadata`).
//!
//! # Macros
//!
//! The declaration surface is built almost entirely from exported macros. This
//! crate defines the language-neutral ones — the domain vocabulary shared by
//! every adapter, plus the syntax helpers they're built from:
//!
//! - Members & constants: [`fun!`](crate::fun)
//! - Conversions: [`convert!`](crate::convert), [`from!`](crate::from),
//! [`try_from!`](crate::try_from), [`into!`](crate::into),
//! [`try_into!`](crate::try_into)
//! - Boundary expansion: [`expand_param!`](crate::expand_param),
//! [`expand_return!`](crate::expand_return), [`fields!`](crate::fields)
//!
//! **Syntax helpers** produce a bare `syn` node — `Type` / `Path` / `Expr` /
//! `Signature` / `Ident` — to hand to a declaration method that requires one.
//! They exist only to sidestep `syn::parse_quote!`'s type-inference ambiguity
//! (E0283) in a generic argument position, not to express a domain concept:
//! [`ty!`](crate::ty), [`path!`](crate::path), [`expr!`](crate::expr),
//! [`sig!`](crate::sig), [`ident!`](crate::ident).
//!
//! The JNI/Kotlin-specific declaration macros — `package!`, `ptr_class!`,
//! `data_class!`, `enum_class!`, `sealed_class!`, `variant!`, `constant!` —
//! construct a typed `*Decl` for the Kotlin surface and live in the separate
//! `prebindgen-jni` crate, which hands the result to its `JniGenBuilder`.
pub
pub
pub
/// The flat model itself lives in the separate `prebindgen-flat` crate —
/// re-exported here so an adapter names one crate root for the whole
/// pipeline.
pub use ;
pub use ;
pub use ;
/// Not part of the public API — referenced by the [`ident!`] macro expansion
/// so callers don't need their own `proc-macro2` dependency just to build a
/// `Span`, by this crate's own decl macros (`fun!`, `convert!`, …), and by the
/// `prebindgen-jni` crate's JNI/Kotlin decl macros (`ptr_class!`, `package!`,
/// …) to parse a bare type token into a concrete `syn::Type`. `pub` (rather
/// than `pub(crate)`) for exactly that cross-crate macro-expansion reason,
/// despite `#[doc(hidden)]`.
/// Build a `syn::Ident` from a bare identifier token. Unlike
/// `syn::parse_quote!`, this always yields the concrete type `syn::Ident` —
/// there's no external context needed to infer it — so it can be passed
/// directly into a generic `impl Into<T>` parameter without hitting rustc's
/// "type annotations needed" ambiguity. `syn::parse_quote!`'s output type
/// has to be pinned by a *concrete* parameter type to infer successfully; a
/// generic `impl Into<T>` bound doesn't give it anything to unify against.
///
/// This is what powers the [`fun!`](crate::fun) decl macro — see that macro
/// (and the `prebindgen-jni` crate's `ptr_class!`/`enum_class!`/`data_class!`,
/// which apply the same trick to `syn::Type`) for the primary way this
/// crate's builders are fed bare Rust names today.
///
/// ```
/// let _: syn::Ident = prebindgen_registry::ident!(z_thing_name);
/// ```