Skip to main content

KtParam

Struct KtParam 

Source
pub struct KtParam {
    pub name: String,
    pub ty: KtType,
    pub default: Option<KtCode>,
}
Expand description

A function parameter with an optional default-value expression.

Fields§

§name: String§ty: KtType§default: Option<KtCode>

Implementations§

Source§

impl KtParam

Source

pub fn new(name: impl Into<String>, ty: KtType) -> Self

Examples found in repository?
examples/showcase.rs (line 83)
61fn types_fragment() -> KtFile {
62    // `enum class` with a primary constructor its entries call, plus a named
63    // companion object holding a factory.
64    let priority = KtClass::enum_("Priority")
65        .vis(KtVis::Public)
66        .kdoc("Delivery priority.\n\nMirrors the native `z_priority_t`.")
67        .ctor_param(
68            KtCtorParam::new("code", KtType::int())
69                .val()
70                .vis(KtVis::Public),
71        )
72        .entry(KtEnumEntry::with_args("REAL_TIME", "1"))
73        .entry(KtEnumEntry::with_args("INTERACTIVE", "4"))
74        .entry(KtEnumEntry::with_args("DATA", "5"))
75        .companion(
76            KtCompanion::named("Codes")
77                .vis(KtVis::Public)
78                .kdoc("Lookup helpers keyed by the native code.")
79                .member(
80                    KtFun::new("fromInt")
81                        .vis(KtVis::Public)
82                        .annotation("JvmStatic")
83                        .param(KtParam::new("value", KtType::int()))
84                        .returns(KtType::cls("Priority"))
85                        .body(
86                            KtCode::new()
87                                .blk("return when (value) {", |c| {
88                                    c.line("1 -> REAL_TIME")
89                                        .line("4 -> INTERACTIVE")
90                                        .line("5 -> DATA")
91                                        .line("else -> throw IllegalArgumentException(\"bad priority: $value\")")
92                                }),
93                        ),
94                ),
95        );
96
97    // `@JvmInline value class` — exactly one read-only property.
98    let zid = KtClass::value(
99        "ZenohId",
100        KtCtorParam::new("bytes", KtType::byte_array())
101            .val()
102            .vis(KtVis::Public),
103    )
104    .vis(KtVis::Public)
105    .kdoc("A 16-byte peer identifier, carried by value.");
106
107    // `data class` — every constructor parameter is a property.
108    let sample = KtClass::data(
109        "Sample",
110        KtCtorParam::new("keyExpr", KtType::string())
111            .val()
112            .vis(KtVis::Public),
113    )
114    .vis(KtVis::Public)
115    .ctor_param(
116        KtCtorParam::new("payload", KtType::byte_array())
117            .val()
118            .vis(KtVis::Public),
119    )
120    .ctor_param(
121        KtCtorParam::new("priority", KtType::cls("Priority"))
122            .val()
123            .vis(KtVis::Public)
124            .default("Priority.DATA"),
125    )
126    .ctor_param(
127        KtCtorParam::new("attachment", KtType::byte_array().nullable())
128            .var()
129            .vis(KtVis::Public)
130            .annotation("JvmField")
131            .default("null"),
132    );
133
134    // A `sealed interface` whose alternatives nest inside it: a `data class`
135    // with a payload and a `data object` without one.
136    let reply = KtClass::sealed_interface("Reply")
137        .vis(KtVis::Public)
138        .kdoc("Either a sample or the end of the stream.")
139        .member(
140            KtClass::data(
141                "Value",
142                KtCtorParam::new("sample", KtType::cls("Sample"))
143                    .val()
144                    .vis(KtVis::Public),
145            )
146            .vis(KtVis::Public)
147            .implements(KtType::cls("Reply")),
148        )
149        .member(
150            KtClass::data_object("Done")
151                .vis(KtVis::Public)
152                .implements(KtType::cls("Reply")),
153        );
154
155    KtFile::new("io.example.api")
156        .decl(priority)
157        .decl(zid)
158        .decl(sample)
159        .decl(reply)
160}
161
162/// The handle surface: an abstract base, a concrete subclass, an interface,
163/// a `fun interface`, and a type alias.
164fn session_fragment() -> KtFile {
165    // `abstract class` with an `abstract` member (bodiless, and it says so),
166    // a `@Volatile` property, and an interface it implements.
167    let base = KtClass::class_with(KtClassModifier::Abstract, "NativeHandle")
168        .vis(KtVis::Public)
169        .kdoc("Owns a raw pointer into Rust and frees it exactly once.")
170        .ctor_param(KtCtorParam::new("initialPtr", KtType::long()))
171        .implements(KtType::cls("AutoCloseable"))
172        .member(
173            KtProperty::var("ptr")
174                .ty(KtType::long())
175                .vis(KtVis::Internal)
176                .annotation("Volatile")
177                .kdoc("Zero once closed.")
178                .initializer("initialPtr"),
179        )
180        .member(
181            KtProperty::val("isClosed")
182                .ty(KtType::boolean())
183                .vis(KtVis::Public)
184                .accessors(KtCode::new().line("get() = ptr == 0L")),
185        )
186        .member(
187            KtFun::new("freePtr")
188                .vis(KtVis::Public)
189                .modifier("abstract")
190                .kdoc("Release the native allocation. Called once, under the lock.")
191                .param(KtParam::new("ptr", KtType::long())),
192        );
193
194    // `open class` extending the abstract base and constructing it.
195    let session = KtClass::class_with(KtClassModifier::Open, "Session")
196        .vis(KtVis::Public)
197        .annotation("Suppress(\"unused\")")
198        .ctor_param(KtCtorParam::new("initialPtr", KtType::long()))
199        .extends(KtType::cls("NativeHandle"), Some("initialPtr"))
200        .implements(KtType::cls("io.example.api.Describable"))
201        .member(
202            KtFun::new("freePtr")
203                .vis(KtVis::Public)
204                .modifier("override")
205                .param(KtParam::new("ptr", KtType::long()))
206                .body(KtCode::new().line("JNINative.sessionFree(ptr)")),
207        )
208        .member(
209            KtFun::new("describe")
210                .vis(KtVis::Public)
211                .modifier("override")
212                .returns(KtType::string())
213                .expr_body(KtCode::new().line("\"Session(0x${ptr.toString(16)})\"")),
214        )
215        // A generic method whose body uses every `KtCode` block form.
216        .member(
217            KtFun::new("get")
218                .vis(KtVis::Public)
219                .generic("R")
220                .kdoc("Run a query, folding each reply into an accumulator.")
221                .param(KtParam::new("selector", KtType::string()))
222                .param(KtParam::new(
223                    "onReply",
224                    KtType::lambda(
225                        [("reply".to_string(), KtType::cls("io.example.api.Reply"))],
226                        KtType::var_r(),
227                    ),
228                ))
229                .param(KtParam::new("timeoutMs", KtType::long()).default("10_000L"))
230                .returns(KtType::generic("List", [KtType::var_r()]))
231                .body(
232                    KtCode::new()
233                        .line("val acc = ArrayList<R>()")
234                        .line("val guard = Guard.acquire(this)")
235                        .import("io.example.internal.Guard")
236                        .try_finally(
237                            "",
238                            KtCode::new().blk("JNINative.sessionGet(ptr, selector, timeoutMs) { raw ->", |c| {
239                                c.line("acc.add(onReply(raw))")
240                            }),
241                            KtCode::new().line("guard.release()"),
242                        )
243                        .line("")
244                        // A long call that the renderer breaks by width at its
245                        // real nesting level.
246                        .wline("reportQueryOutcome(selector, timeoutMs, acc.size, acc.isNotEmpty(), \"query finished\", System.nanoTime())")
247                        .line("return acc"),
248                ),
249        )
250        // The interface's member extension, implemented.
251        .member(
252            KtFun::new("label")
253                .vis(KtVis::Public)
254                .modifier("override")
255                .receiver(KtType::cls("Sample"))
256                .returns(KtType::string())
257                .expr_body(KtCode::new().line("\"${keyExpr}@${describe()}\"")),
258        )
259        // A member extension of the class itself.
260        .member(
261            KtFun::new("toSample")
262                .vis(KtVis::Public)
263                .receiver(KtType::byte_array())
264                .returns(KtType::cls("Sample"))
265                .expr_body(KtCode::new().line("Sample(describe(), this)")),
266        )
267        // A nested class — its own scope, so its members may reuse names.
268        .member(
269            KtClass::class_("Config")
270                .vis(KtVis::Public)
271                .member(KtProperty::val("describe").initializer("\"config\"")),
272        )
273        .companion(
274            KtCompanion::new()
275                .vis(KtVis::Public)
276                .member(
277                    KtFun::new("open")
278                        .vis(KtVis::Public)
279                        .annotation("JvmStatic")
280                        .param(KtParam::new("config", KtType::string()).default("\"{}\""))
281                        .returns(KtType::cls("Session"))
282                        .expr_body(KtCode::new().line("Session(JNINative.sessionOpen(config))")),
283                ),
284        );
285
286    // A plain `interface`: bodiless members are abstract by position, and a
287    // `KtFunSig` is exactly that.
288    let describable = KtClass::interface_("Describable")
289        .vis(KtVis::Public)
290        .member(KtFunSig::new("describe").returns(KtType::string()))
291        // A member extension: abstract here, supplied by the implementor.
292        // `KtFunSig` carries a receiver too, so a signature does not quietly
293        // become a plain member.
294        .member(
295            KtFunSig::new("label")
296                .receiver(KtType::cls("Sample"))
297                .returns(KtType::string()),
298        );
299
300    // A `fun interface` (SAM) — its single method cannot carry a body.
301    let handler = KtFunInterface::new(
302        "ReplyHandler",
303        KtFunSig::new("onReply")
304            .param(KtParam::new("reply", KtType::cls("Reply")))
305            .returns(KtType::var_r()),
306    )
307    .vis(KtVis::Public)
308    .type_param("out R")
309    .kdoc("Invoked from the native thread for each reply.");
310
311    // Top-level extension functions. The receiver is a type, not part of the
312    // name, so it resolves through the import set and the name stays a plain
313    // identifier the validator can check as one.
314    let summary = KtFun::new("summary")
315        .vis(KtVis::Public)
316        .receiver(KtType::cls("Sample"))
317        .returns(KtType::string())
318        .expr_body(KtCode::new().line("\"$keyExpr (${payload.size} bytes)\""));
319
320    // Generics render before the receiver, which renders before the name.
321    let map_replies = KtFun::new("mapValues")
322        .vis(KtVis::Public)
323        .generic("R")
324        .receiver(KtType::generic("List", [KtType::cls("Reply")]))
325        .param(KtParam::new(
326            "transform",
327            KtType::lambda(
328                [("sample".to_string(), KtType::cls("Sample"))],
329                KtType::var_r(),
330            ),
331        ))
332        .returns(KtType::generic("List", [KtType::var_r()]))
333        .expr_body(
334            KtCode::new().line("filterIsInstance<Reply.Value>().map { transform(it.sample) }"),
335        );
336
337    // An extension on a *function type*. The receiver needs parentheses here
338    // or the `.` would bind to the return type instead.
339    let as_raw = KtFun::new("asRaw")
340        .vis(KtVis::Internal)
341        .receiver(KtType::lambda(
342            [("sample".to_string(), KtType::cls("Sample"))],
343            KtType::unit(),
344        ))
345        .returns(KtType::cls("io.example.api.internal.RawSink"))
346        // The proxy adapts a typed callback to the raw one the natives call,
347        // so it has to narrow `Reply` to the `Sample` the receiver takes.
348        .expr_body(
349            KtCode::new().line("RawSink { raw -> if (raw is Reply.Value) this(raw.sample) }"),
350        );
351
352    KtFile::new("io.example.api")
353        // FQNs named only from raw body text, which the model cannot see.
354        .imports(["io.example.api.internal.JNINative".to_string()])
355        .decl(base)
356        .decl(describable)
357        .decl(handler)
358        .decl(session)
359        .decl(summary)
360        .decl(map_replies)
361        .decl(as_raw)
362        .decl(KtDecl::TypeAlias {
363            vis: KtVis::Public,
364            name: "SampleList".to_string(),
365            target: KtType::generic("List", [KtType::cls("Sample")]),
366        })
367}
368
369/// The `external` surface — an object of natives, in its own subpackage.
370fn natives_fragment() -> KtFile {
371    let natives = KtClass::object_("JNINative")
372        .vis(KtVis::Internal)
373        .kdoc("One-to-one with the exported Rust symbols.")
374        .member(
375            KtFun::new("sessionOpen")
376                .vis(KtVis::Internal)
377                .param(KtParam::new("config", KtType::string()))
378                .returns(KtType::long())
379                .external(),
380        )
381        .member(
382            KtFun::new("sessionFree")
383                .vis(KtVis::Internal)
384                .param(KtParam::new("ptr", KtType::long()))
385                .external(),
386        )
387        .member(
388            KtFun::new("sessionGet")
389                .vis(KtVis::Internal)
390                .param(KtParam::new("ptr", KtType::long()))
391                .param(KtParam::new("selector", KtType::string()))
392                .param(KtParam::new("timeoutMs", KtType::long()))
393                .param(KtParam::new(
394                    "sink",
395                    KtType::lambda(
396                        [("reply".to_string(), KtType::cls("io.example.api.Reply"))],
397                        KtType::unit(),
398                    ),
399                ))
400                .external(),
401        );
402
403    // A pre-rendered block, for text the model does not describe. Its name is
404    // a merge identity, never emitted.
405    let loader = KtDecl::Raw {
406        name: "__loadNative".to_string(),
407        code: KtCode::raw_reindent(
408            "internal val __loaded: Boolean = run {\n\
409             System.loadLibrary(\"example_jni\")\n\
410             true\n\
411             }",
412        ),
413    };
414
415    let raw_sink = KtFunInterface::new(
416        "RawSink",
417        KtFunSig::new("accept").param(KtParam::new("reply", KtType::cls("io.example.api.Reply"))),
418    )
419    .vis(KtVis::Internal);
420
421    KtFile::new("io.example.api.internal")
422        .decl(raw_sink)
423        .decl(natives)
424        .decl(loader)
425        // An FQN referenced only from raw text the model cannot see.
426        .import("io.example.api.Reply")
427}
428
429/// A file in the default (root) package, exercising a banner override and
430/// top-level declarations of every value kind.
431fn root_fragment() -> KtFile {
432    KtFile::new("")
433        .banner("// Hand-tuned banner for the root package.")
434        .decl(
435            KtProperty::val("LIBRARY_VERSION")
436                .ty(KtType::string())
437                .vis(KtVis::Public)
438                .kdoc("Version this binding was generated against.")
439                .initializer("\"1.9.0\""),
440        )
441        // A keyword modifier rendered between visibility and `val`.
442        .decl(
443            KtProperty::val("PROTOCOL")
444                .ty(KtType::string())
445                .vis(KtVis::Public)
446                .modifier("const")
447                .initializer("\"tcp\""),
448        )
449        // A delegated property: `by <expr>` rather than `= <expr>`.
450        .decl(
451            KtProperty::val("defaultTimeout")
452                .vis(KtVis::Internal)
453                .ty(KtType::cls("java.time.Duration"))
454                .delegate("lazy { Duration.ofSeconds(10) }"),
455        )
456        .decl(
457            KtFun::new("describeAll")
458                .vis(KtVis::Public)
459                // Generic parameter lists are free-form text, so a bound is
460                // written as given — it is not shortened against the imports.
461                .generic("T : io.example.api.Describable")
462                .param(KtParam::new(
463                    "items",
464                    KtType::generic("List", [KtType::var_("T")]),
465                ))
466                .returns(KtType::string())
467                .expr_body(KtCode::new().line("items.joinToString { it.describe() }")),
468        )
469}
More examples
Hide additional examples
examples/invalid.rs (line 89)
71fn broken_declarations() -> KtFile {
72    KtFile::new("io.example.broken")
73        // Two classes of the same name: a redeclaration in the type namespace.
74        .decl(KtClass::class_("Session"))
75        .decl(KtClass::class_("Session"))
76        // An interface and a type alias are both classifier declarations, so they collide.
77        .decl(
78            KtClass::interface_("Describable")
79                .member(KtFun::new("describe").returns(KtType::string())),
80        )
81        .decl(KtDecl::TypeAlias {
82            vis: KtVis::Public,
83            name: "Describable".to_string(),
84            target: KtType::string(),
85        })
86        // Same name AND same parameter types: not an overload.
87        .decl(
88            KtFun::new("send")
89                .param(KtParam::new("value", KtType::int()))
90                .returns(KtType::boolean())
91                .body(KtCode::new()),
92        )
93        .decl(
94            KtFun::new("send")
95                .param(KtParam::new("other", KtType::int()))
96                .returns(KtType::long())
97                .body(KtCode::new()),
98        )
99        // Extensions are keyed on their receiver, so these two collide while
100        // the same pair on different receivers would not.
101        .decl(
102            KtFun::new("asRaw")
103                .receiver(KtType::cls("io.example.Codec"))
104                .body(KtCode::new()),
105        )
106        .decl(
107            KtFun::new("asRaw")
108                .receiver(KtType::cls("io.example.Codec"))
109                .body(KtCode::new()),
110        )
111        // ...as here: same name, different receiver, no diagnostic.
112        .decl(
113            KtFun::new("asRaw")
114                .receiver(KtType::cls("io.example.Other"))
115                .body(KtCode::new()),
116        )
117        // Names that are not legal Kotlin identifiers.
118        .decl(
119            KtClass::class_("My-Class")
120                .ctor_param(KtCtorParam::new("2fast", KtType::int()))
121                .member(
122                    KtFun::new("object")
123                        .param(KtParam::new("in", KtType::int()))
124                        .body(KtCode::new()),
125                ),
126        )
127        // `val x` with no type, no value and no accessors.
128        .decl(KtProperty::val("bare"))
129        // A function with no body, at top level, where that cannot mean
130        // "abstract".
131        .decl(KtFun::new("nobody"))
132        // An abstract class member missing the `abstract` keyword.
133        .decl(
134            KtClass::class_with(KtClassModifier::Abstract, "Base")
135                .member(KtFun::new("unimplemented")),
136        )
137        // An enum whose entries do not call the constructor it declares.
138        .decl(
139            KtClass::enum_("Priority")
140                .ctor_param(KtCtorParam::new("code", KtType::int()).val())
141                .entry(KtEnumEntry::with_args("HIGH", "1"))
142                .entry(KtEnumEntry::new("LOW")),
143        )
144        // A constructor property and a member property of one name: both live
145        // in the value namespace.
146        .decl(
147            KtClass::class_("Holder")
148                .ctor_param(KtCtorParam::new("id", KtType::long()).val())
149                .member(KtProperty::val("id").initializer("0")),
150        )
151        // A named companion object colliding with a nested class.
152        .decl(
153            KtClass::class_("Outer")
154                .member(KtClass::class_("Factory"))
155                .companion(KtCompanion::named("Factory")),
156        )
157        // Two raw blocks claiming one identity with different bodies.
158        .decl(KtDecl::Raw {
159            name: "__loader".to_string(),
160            code: KtCode::new().line("internal val __loader = 1"),
161        })
162        .decl(KtDecl::Raw {
163            name: "__loader".to_string(),
164            code: KtCode::new().line("internal val __loader = 2"),
165        })
166        // Two different classes referenced from raw text under one short name:
167        // the text already says `Codec`, so it cannot mean both.
168        .import("io.example.a.Codec")
169        .import("io.example.b.Codec")
170}
Source

pub fn default(self, d: impl Into<String>) -> Self

Examples found in repository?
examples/showcase.rs (line 229)
164fn session_fragment() -> KtFile {
165    // `abstract class` with an `abstract` member (bodiless, and it says so),
166    // a `@Volatile` property, and an interface it implements.
167    let base = KtClass::class_with(KtClassModifier::Abstract, "NativeHandle")
168        .vis(KtVis::Public)
169        .kdoc("Owns a raw pointer into Rust and frees it exactly once.")
170        .ctor_param(KtCtorParam::new("initialPtr", KtType::long()))
171        .implements(KtType::cls("AutoCloseable"))
172        .member(
173            KtProperty::var("ptr")
174                .ty(KtType::long())
175                .vis(KtVis::Internal)
176                .annotation("Volatile")
177                .kdoc("Zero once closed.")
178                .initializer("initialPtr"),
179        )
180        .member(
181            KtProperty::val("isClosed")
182                .ty(KtType::boolean())
183                .vis(KtVis::Public)
184                .accessors(KtCode::new().line("get() = ptr == 0L")),
185        )
186        .member(
187            KtFun::new("freePtr")
188                .vis(KtVis::Public)
189                .modifier("abstract")
190                .kdoc("Release the native allocation. Called once, under the lock.")
191                .param(KtParam::new("ptr", KtType::long())),
192        );
193
194    // `open class` extending the abstract base and constructing it.
195    let session = KtClass::class_with(KtClassModifier::Open, "Session")
196        .vis(KtVis::Public)
197        .annotation("Suppress(\"unused\")")
198        .ctor_param(KtCtorParam::new("initialPtr", KtType::long()))
199        .extends(KtType::cls("NativeHandle"), Some("initialPtr"))
200        .implements(KtType::cls("io.example.api.Describable"))
201        .member(
202            KtFun::new("freePtr")
203                .vis(KtVis::Public)
204                .modifier("override")
205                .param(KtParam::new("ptr", KtType::long()))
206                .body(KtCode::new().line("JNINative.sessionFree(ptr)")),
207        )
208        .member(
209            KtFun::new("describe")
210                .vis(KtVis::Public)
211                .modifier("override")
212                .returns(KtType::string())
213                .expr_body(KtCode::new().line("\"Session(0x${ptr.toString(16)})\"")),
214        )
215        // A generic method whose body uses every `KtCode` block form.
216        .member(
217            KtFun::new("get")
218                .vis(KtVis::Public)
219                .generic("R")
220                .kdoc("Run a query, folding each reply into an accumulator.")
221                .param(KtParam::new("selector", KtType::string()))
222                .param(KtParam::new(
223                    "onReply",
224                    KtType::lambda(
225                        [("reply".to_string(), KtType::cls("io.example.api.Reply"))],
226                        KtType::var_r(),
227                    ),
228                ))
229                .param(KtParam::new("timeoutMs", KtType::long()).default("10_000L"))
230                .returns(KtType::generic("List", [KtType::var_r()]))
231                .body(
232                    KtCode::new()
233                        .line("val acc = ArrayList<R>()")
234                        .line("val guard = Guard.acquire(this)")
235                        .import("io.example.internal.Guard")
236                        .try_finally(
237                            "",
238                            KtCode::new().blk("JNINative.sessionGet(ptr, selector, timeoutMs) { raw ->", |c| {
239                                c.line("acc.add(onReply(raw))")
240                            }),
241                            KtCode::new().line("guard.release()"),
242                        )
243                        .line("")
244                        // A long call that the renderer breaks by width at its
245                        // real nesting level.
246                        .wline("reportQueryOutcome(selector, timeoutMs, acc.size, acc.isNotEmpty(), \"query finished\", System.nanoTime())")
247                        .line("return acc"),
248                ),
249        )
250        // The interface's member extension, implemented.
251        .member(
252            KtFun::new("label")
253                .vis(KtVis::Public)
254                .modifier("override")
255                .receiver(KtType::cls("Sample"))
256                .returns(KtType::string())
257                .expr_body(KtCode::new().line("\"${keyExpr}@${describe()}\"")),
258        )
259        // A member extension of the class itself.
260        .member(
261            KtFun::new("toSample")
262                .vis(KtVis::Public)
263                .receiver(KtType::byte_array())
264                .returns(KtType::cls("Sample"))
265                .expr_body(KtCode::new().line("Sample(describe(), this)")),
266        )
267        // A nested class — its own scope, so its members may reuse names.
268        .member(
269            KtClass::class_("Config")
270                .vis(KtVis::Public)
271                .member(KtProperty::val("describe").initializer("\"config\"")),
272        )
273        .companion(
274            KtCompanion::new()
275                .vis(KtVis::Public)
276                .member(
277                    KtFun::new("open")
278                        .vis(KtVis::Public)
279                        .annotation("JvmStatic")
280                        .param(KtParam::new("config", KtType::string()).default("\"{}\""))
281                        .returns(KtType::cls("Session"))
282                        .expr_body(KtCode::new().line("Session(JNINative.sessionOpen(config))")),
283                ),
284        );
285
286    // A plain `interface`: bodiless members are abstract by position, and a
287    // `KtFunSig` is exactly that.
288    let describable = KtClass::interface_("Describable")
289        .vis(KtVis::Public)
290        .member(KtFunSig::new("describe").returns(KtType::string()))
291        // A member extension: abstract here, supplied by the implementor.
292        // `KtFunSig` carries a receiver too, so a signature does not quietly
293        // become a plain member.
294        .member(
295            KtFunSig::new("label")
296                .receiver(KtType::cls("Sample"))
297                .returns(KtType::string()),
298        );
299
300    // A `fun interface` (SAM) — its single method cannot carry a body.
301    let handler = KtFunInterface::new(
302        "ReplyHandler",
303        KtFunSig::new("onReply")
304            .param(KtParam::new("reply", KtType::cls("Reply")))
305            .returns(KtType::var_r()),
306    )
307    .vis(KtVis::Public)
308    .type_param("out R")
309    .kdoc("Invoked from the native thread for each reply.");
310
311    // Top-level extension functions. The receiver is a type, not part of the
312    // name, so it resolves through the import set and the name stays a plain
313    // identifier the validator can check as one.
314    let summary = KtFun::new("summary")
315        .vis(KtVis::Public)
316        .receiver(KtType::cls("Sample"))
317        .returns(KtType::string())
318        .expr_body(KtCode::new().line("\"$keyExpr (${payload.size} bytes)\""));
319
320    // Generics render before the receiver, which renders before the name.
321    let map_replies = KtFun::new("mapValues")
322        .vis(KtVis::Public)
323        .generic("R")
324        .receiver(KtType::generic("List", [KtType::cls("Reply")]))
325        .param(KtParam::new(
326            "transform",
327            KtType::lambda(
328                [("sample".to_string(), KtType::cls("Sample"))],
329                KtType::var_r(),
330            ),
331        ))
332        .returns(KtType::generic("List", [KtType::var_r()]))
333        .expr_body(
334            KtCode::new().line("filterIsInstance<Reply.Value>().map { transform(it.sample) }"),
335        );
336
337    // An extension on a *function type*. The receiver needs parentheses here
338    // or the `.` would bind to the return type instead.
339    let as_raw = KtFun::new("asRaw")
340        .vis(KtVis::Internal)
341        .receiver(KtType::lambda(
342            [("sample".to_string(), KtType::cls("Sample"))],
343            KtType::unit(),
344        ))
345        .returns(KtType::cls("io.example.api.internal.RawSink"))
346        // The proxy adapts a typed callback to the raw one the natives call,
347        // so it has to narrow `Reply` to the `Sample` the receiver takes.
348        .expr_body(
349            KtCode::new().line("RawSink { raw -> if (raw is Reply.Value) this(raw.sample) }"),
350        );
351
352    KtFile::new("io.example.api")
353        // FQNs named only from raw body text, which the model cannot see.
354        .imports(["io.example.api.internal.JNINative".to_string()])
355        .decl(base)
356        .decl(describable)
357        .decl(handler)
358        .decl(session)
359        .decl(summary)
360        .decl(map_replies)
361        .decl(as_raw)
362        .decl(KtDecl::TypeAlias {
363            vis: KtVis::Public,
364            name: "SampleList".to_string(),
365            target: KtType::generic("List", [KtType::cls("Sample")]),
366        })
367}

Trait Implementations§

Source§

impl Clone for KtParam

Source§

fn clone(&self) -> KtParam

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for KtParam

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.