Pojson is a kotlin library for json prototyping. It brings DSL for building JsonObjectPrototype
and JsonArrayPrototype
. Prototypes don't reference to any json object/array models. You can choose implementation you want to use for rendering json. Simple json prototype may looks like:
val prototype = JsonObjectPrototype {
"my-string-property" % "Hello, world!"
"my-number-property" % 42L
"my-object-property" % obj {
"my-nested-object-property" % true
}
"my-array-property" % array {
element("Hello, world!")
element(42L)
element(true)
}
}
Actually Pojson
is a kotlin class with methods render
for object and array.
val prototype = JsonObjectPrototype {
..
}
val pojson = Pojson(..)
pojson.render(prototype) // Returns selected json object representation
Pojson
constructor requires implementation of interfaces JsonObjectFactory
, JsonArrayFactory
, JsonObjectAdapter
, JsonArrayAdapter
. Usually implementation of this interfaces is a simple task. You can implement this interfaces manually or use one of existing integration with json object/array representation.
val prototype = JsonObjectPrototype {
..
}
Pojson2Gson.create().render(prototype) // Returns com.google.gson.JsonObject
Pojson2AndroidJSON.create().render(prototype) // Returns org.json.JSONObject
Pojson2KotlinCollection.create().render(prototype) // Returns kotlin.collections.MutableMap
Pojson provides class JsonObjectPrototype
with constructor as entry point for object notation.
JsonObjectPrototype {
..
}
Pojson provides overloaded operator %
for assigning value to key in object notation.
JsonObjectPrototype {
"my-property" % "my-value"
}
Pojson provides class JsonArrayPrototype
with constructor as entry point for array notation.
JsonArrayPrototype {
..
}
You can create array shortly if all elements has the same type.
JsonArrayPrototype.strings("foo", "bar", "baz")
JsonArrayPrototype.numbers(1, 2, 42)
JsonArrayPrototype.objects(list) { item ->
// object format logic, dsl available
..
}
Pojson provides element(..)
method for appending items to array.
JsonArrayPrototype {
element(42L)
element("Hello, world!")
}
Pojson provides method obj { .. }
for nested object instantiation.
JsonObjectPrototype {
"my-property" % obj {
"my-nested-property" % "my-nested-value"
}
}
Also you can call obj { .. }
with context.
JsonObjectPrototype {
"my-property" % obj(model) {
"my-nested-property" % it.name
}
}
Pojson provides method array { .. }
for nested array instantiation.
JsonObjectPrototype {
"my-property" % array {
..
}
}
Pojson provides shortcuts for nested arrays if all elements has the same type.
JsonObjectPrototype {
"my-strings-property" % arrayOfStrings("foo", "bar", "baz")
"my-numbers-property" % arrayOfNumbers(1, 2, 42)
"my-booleans-property" % arrayOfBooleans(true, true, false)
"my-objects-property" % arrayOfObjects(models) { model ->
..
}
}
By default pojson requires all values to be non-null.
If you want to work with nullable values you should specify it explicitly.
Pojson provides method nullable
for this purpose.
val myString: String? = "Hello, world!"
// Not working
JsonObjectPrototype {
"my-property" % myString // IDE error: expected [String] but found [String?]
}
// Working
JsonObjectPrototype {
"my-property" % nullable(myString) // No error, correct type inference
}
Also pojson provides utility methods nullString
, nullNumber
, nullBoolean
, nullObject
and nullArray
for kotlin type inference when you want to use if-else expressions inside object/array notation.
JsonObjectPrototype {
"my-property" % if (myFlag) obj {
..
} else nullObject()
}
Pojson provides capability to composite prototypes.
val manufacturer = JsonObjectPrototype {
"name" % "Land Rover"
"country" % "United Kingdom"
}
val car = JsonObjectPrototype {
"model" % "Defender"
"year" % 2017
"manufacturer" % manufacturer
}
Pojson provides capability to merge prototype properties into another prototype.
val design = JsonObjectPrototype {
"color" % "black"
"wheels" % "20.0 inch"
}
val car = JsonObjectPrototype {
"model" % "Defender"
"year" % 2017
merge(design)
}
or
fun formatDesign(): JsonObjectNotation = {
"color" % "black"
"wheels" % "20.0 inch"
}
fun formatCar(): JsonObjectNotation = {
"model" % "Defender"
"year" % 2017
merge(formatDesign())
}
Also you can merge arrays in the same manner.
val vowels = JsonArrayPrototype {
for (letter in listOf("A", "E", "I", "O", "U")) {
element(letter)
}
}
val consonants = JsonArrayPrototype {
for (letter in listOf("B", "C", "D", "F", "G", "H", ..)) {
element(letter)
}
}
val letters = JsonArrayPrototype {
merge(vowels)
merge(consonants)
}
or
fun formatVowels(): JsonArrayNotation {
for (letter in listOf("A", "E", "I", "O", "U")) {
element(letter)
}
}
fun formatConsonants(): JsonArrayNotation {
for (letter in listOf("B", "C", "D", "F", "G", "H", ..)) {
element(letter)
}
}
fun formatLetters(): JsonArrayNotation {
merge(vowels)
merge(consonants)
}
Core module contains syntax declaration without integrations with third-party solutions.
dependencies {
implementation 'io.github.acelost:pojson-core:${latestVersion}'
}
Gson module contains syntax declaration plus integration with gson object model. You can render prototypes to com.google.gson.JsonObject
and com.google.gson.JsonArray
.
dependencies {
implementation 'io.github.acelost:pojson-gson:${latestVersion}'
}
Android Json module contains syntax declaration plus integration with native android object model. You can render prototypes to org.json.JSONObject
and org.json.JSONArray
.
dependencies {
implementation 'io.github.acelost:pojson-android-json:${latestVersion}'
}
Koltin Collection module contains syntax declaration plus integration with kotlin collections. You can render prototypes to kotlin.collections.Map
and kotlin.collections.List
.
dependencies {
implementation 'io.github.acelost:pojson-kotlin-collection:${latestVersion}'
}