https://kotlinlang.org logo
#feed
Title
# feed
b

Big Chungus

10/14/2021, 10:53 AM
Ever wanted to just build a nice json in kotlin, but found raw string templates hard to keep pretty? Well turns out you can make full json DSL with just a few lines of code.
💡 2
K 3
👌 10
mind blown 3
👏 1
😮 1
🆒 1
Serializes to this
Copy code
{
  "boolean": true,
  "number": 1,
  "string": "str",
  "null": null,
  "array": [
    1,
    "str",
    null,
    {},
    [
      1,
      "2",
      null,
      3
    ]
  ],
  "object": {
    "boolean": true,
    "number": 1,
    "string": "str",
    "null": null,
    "array": [
      1,
      "str",
      null
    ]
  }
}
r

Robert Jaros

10/14/2021, 11:05 AM
Serializes with what? kotlinx.serialization?
b

Big Chungus

10/14/2021, 11:06 AM
With whatever you choose. This just builds a map representation of json.
i.e. It doesn't depend on any serialization voodoo to work.
But for transparency, I ran the generated map through Jackson to get that json output.
1
a

arekolek

10/14/2021, 12:17 PM
You can also use the "inject language" feature in the IDE
👍 4
b

Big Chungus

10/14/2021, 12:26 PM
I'm aware, but I found that hard to maintain in terms of formatting. Plus it adds lots of
$
that just feels unnatural. I found the DSL much more comfortable to work with as it closer matches json structure and allows direct references to variables (no
$
required)
j

Javier

10/14/2021, 2:07 PM
kotlin serialization had something similar to this no? but they changed to
build...
functions
b

Big Chungus

10/14/2021, 2:09 PM
Did they? I'm not aware of that. Got a link?
j

Javier

10/14/2021, 2:10 PM
I can't found one, it was removed a lot of months ago
by
can't be replaced by
operator fun equals
?
b

Big Chungus

10/14/2021, 2:20 PM
Hmm, good idea! Or +=
Not sure which is better
j

Javier

10/14/2021, 2:35 PM
personally when I create manually a Json I always fail and I use = instead of :
that is the reason I thought in = hahah
any way, are you going to publish it as KMP library? not a lot of code, but it can be used in a lot of projects so avoid copypasting can be great
t

Tobias Berger

10/14/2021, 2:41 PM
something interesting I saw in a DSL for JSON objects once: instead of the
by
infix function, you could implement a
rangeTo
operator function, so
Copy code
{
    "number" by 1
}
becomes
Copy code
{
    "number"..1
}
which looks a bit like the
:
just fell over 😄
😂 2
@Javier
equals
already exists on every type and extension functions can't override member functions. Also, it would result in the usage of
==
, not
=
and wouldn't work properly with null values (if I remember the behaviour correctly)
j

jimn

10/14/2021, 3:04 PM
i like operator %, it has two dots also https://gist.github.com/jnorthrup/51f2b23bde522bb03d74aa552c295f6b it feels like there are some wicked delegation opportunities
j

Javier

10/14/2021, 3:06 PM
ah, not sure if
=
can be used or only
==
t

Tobias Berger

10/14/2021, 3:08 PM
=
assigns a value, the equality check is always
==
j

Javier

10/14/2021, 3:09 PM
yeah, but there is no another operator for it no?
maybe
to
to keep consistence with languages features if
=
cant be used
👆 2
j

jimn

10/14/2021, 3:39 PM
Copy code
infix operator fun String.rem(value: Any?) = this `⁚` value //two escaped dots if inlined
    
    @JSSetterDsl
    /**
     * set primitive
     */
    infix fun String.`⁚`(t: Any?) { map[this] = t }  
...
val `{}` by lazy { JSObj().apply(fun JSObj.() = Unit) }
some options. alternatives to backticks would be great in kotlin.
b

Big Chungus

10/14/2021, 3:53 PM
Backticks are a big nono for mpp projects thanks to js 😀
j

Javier

10/14/2021, 4:01 PM
and they are hard to write, sadly
b

Big Chungus

10/14/2021, 5:05 PM
Ok well, I went ahead and published that as an MPP lib 😄 It even builds json strings for you! kon@1.0.0 is out! All proposed setters are supported with the exception of
==
and backticks.
K 1
👏 1
👍 4
🆒 1
j

Javier

10/14/2021, 6:44 PM
Copy code
Modules
kon - wrapper module
this link is broken
b

Big Chungus

10/14/2021, 6:45 PM
What do you mean?
Nvm, figured it out and fixed it
o

Oliver.O

10/14/2021, 9:01 PM
I like the idea but I'm worried about the operator overkill: Code written by multiple persons can become hard to read if one person would use
by
, the second adds stuff with
%
, and so on. I'd stick with the usual
to
as this aligns with Kotlin map notation, and avoid synonymous operators.
👍 2
b

Big Chungus

10/14/2021, 10:38 PM
I had same thoughts. I'll use it in my own projects for the next week and will decide on what feels most natural. The rest will be removed. Also I'm a bit iffy about using to as there's an infix function like that in stdlib already used to build pairs. Shadowing might be an issue
j

Javier

10/14/2021, 10:47 PM
I think
to
is enough and it is used to build maps, I like += too.
b

Big Chungus

10/14/2021, 11:49 PM
How about just +? It's the same hey on the keyboard
Although it doesn't convey the intent as well...
j

Javier

10/15/2021, 2:01 AM
+ for standalone values is fine, but in json there are not standalone values, semantically looks strange
e

ephemient

10/15/2021, 9:20 AM
did anybody bring up the json builders in kotlinx.serialization? they're a bit more verbose but they do exist (buildJsonObject, buildJsonArray, etc.)
b

Big Chungus

10/15/2021, 9:22 AM
@Javier did but couldn't get a link 😄 Also to get them you have to bring in entire serialization lib (heavy), which might not always be what you want.
j

Javier

10/15/2021, 9:24 AM
Maybe you can find the commit where they moved to
build...
Another cool thing you can add to your lib, is compatibility with Kotlin Serialization
so you generate a
JsonElement
with your syntax
b

Big Chungus

10/15/2021, 9:25 AM
I'm thinking of adding that as a new module. So ppl could still use it without serialization
e

ephemient

10/15/2021, 9:27 AM
o

Oliver.O

10/15/2021, 11:09 AM
@ephemient Thanks for bringing that up. Some thoughts: The
kotlinx.serialization
API seems to ease onboarding (with IDE support, you'd just type
put
and use completion). I am undecided whether its verbosity might increase reading/scanning time when compared to a map-like
to
notation. Probably not much, if at all. In the end, I tend to think it is like using different indentation styles: While I do prefer certain styles over others, what really matters most is consistency.
b

Big Chungus

10/15/2021, 1:33 PM
Apologies for the spam, but kon@1.1.0 is out with standardised setters and optional kontinx-serialization-json support for two-way conversions between
KON
and
JsonObject
👍 4
m

Matteo Mirk

10/15/2021, 3:10 PM
yeah this is better! When I saw all those different operators to perform the same action i was very confused
e

ephemient

10/15/2021, 8:30 PM
"array"[1]
in KObject may be an issue… what if you changed the DSL to
Copy code
kobj {
  "scalar" to 1
  "object".to { ... }
  "array".to[ ... ]
}
instead? seems more consistent to me
b

Big Chungus

10/15/2021, 9:37 PM
Why is String[] an issue? That extension is only available in kobject scope and hooks onto string class
Or do you mean string char accessor overlap?
I'll do some testing to see how relevant it actually is
e

ephemient

10/15/2021, 10:36 PM
yes, it'll resolve to String.get over your extension
7 Views