Daniel Pitts
11/10/2024, 6:17 PMkson
for now). (Example code here)
2. Type safe Json wrapper with JsonSchema generation and validation. (Example code here). This feature was heavily inspired by Exposed DAO.
I will add examples of the DSLs in 🧵 too.
Please let me know any thoughts or suggestions.Daniel Pitts
11/10/2024, 6:18 PMDaniel Pitts
11/10/2024, 6:19 PMCLOVIS
11/12/2024, 1:00 PMkson
… https://search.maven.org/search?q=ksonCLOVIS
11/12/2024, 1:01 PMDaniel Pitts
11/12/2024, 3:40 PMDaniel Pitts
11/12/2024, 3:41 PMCLOVIS
11/12/2024, 4:43 PM/=
here. If possible, I try to avoid using operators for something that symbol is not closely associated with. Here, I would probably just use set
I would also use this to simplify the nullable case. In your type unsafe example, you're using ?.field()
which is the opposite order as the rest of the DSL. Instead, you could have something like:
kson {
…
"isMarried" set (spouse != null)
"spouse" setNotNull spouse
"spouseDetails" setNotNull details
…
}
an example of this pattern in one of my DSLs: https://opensavvy.gitlab.io/ktmongo/api-docs/dsl/opensavvy.ktmongo.dsl.expr/-filter-expression/eq-not-null.html?query=infix%20fun%20%3CV%3E%20Field%3CT,%20V%3E.eqNotNull(value:%20V?)
In general, I'm not a fan of the existence of unsafe DSLs, but sometimes they are necessary…CLOVIS
11/12/2024, 4:44 PMcompanion object Schema
is nice, but the outer class is just boilerplate. Maybe have something like:
Example(…)[Schema.foo]
?
but that's verbose on the call-site, which is not necessarily betterDaniel Pitts
11/12/2024, 4:47 PMCLOVIS
11/12/2024, 4:48 PMobject Example : CompoundClass<Example>({ Example(it) }) {
val foo = string("foo")
val bar = int("bar")
val baz = ExampleSubObject("baz")
val qux = jsonArray("qux").withItems(string)
val quux = union("quux")
val quuxString = quux[string].nullable()
val quuxInt = quux[int]
val quuxObj = quux[jsonObject]
}
class WithData(private val wrapper: JsonObject) {
operator fun Field.invoke() = wrapper[this]
}
fun withData(obj: JsonObject, block: WithData() -> Unit) {
WithData(obj).apply(block)
}
val wrapper: JsonObject = TODO()
withData(wrapper) {
println(Example.foo())
}
This would be similar to the way I implemented suspend
scoped properties here: https://opensavvy.gitlab.io/groundwork/prepared/api-docs/suite/opensavvy.prepared.suite/-prepared/index.htmlDaniel Pitts
11/12/2024, 4:49 PM