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
impl KtParam
Sourcepub fn new(name: impl Into<String>, ty: KtType) -> Self
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
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}Sourcepub fn default(self, d: impl Into<String>) -> Self
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§
Auto Trait Implementations§
impl Freeze for KtParam
impl RefUnwindSafe for KtParam
impl Send for KtParam
impl Sync for KtParam
impl Unpin for KtParam
impl UnsafeUnpin for KtParam
impl UnwindSafe for KtParam
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more