Skip to content

Commit fb50ddb

Browse files
committed
Add default args. Add example. Add docs. Set version
1 parent 5a65a0b commit fb50ddb

File tree

4 files changed

+98
-10
lines changed

4 files changed

+98
-10
lines changed

README.md

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ println(CustomPPrinter5(PPrinterConfig()).invoke(p))
402402
//> PersonBorn(name = "Joe")
403403
```
404404
405-
## Using `elementName` metadata - Kotlin Multiplatform
405+
## Using `elementName` metadata in Kotlin Multiplatform
406406
407407
If you want to filter out fields based on `elementName` in Kotlin Multiplatform inside of the PPrinter you need to override
408408
the `treeifyComposite` method.
@@ -430,7 +430,7 @@ println(CustomPPrinter6<PersonBorn>(PersonBorn.serializer(), PPrinterConfig()).i
430430
//> PersonBorn(name = "Joe")
431431
```
432432
433-
#### Sealed Hierarchies in KMP
433+
#### Sealed Hierarchies in Kotlin Multiplatform
434434
435435
According to the `kotlinx-serialization` documentation, every member of a sealed hierarchy must be annotated with `@Serializable`.
436436
For example, in the following hierarchy:
@@ -448,7 +448,57 @@ Every member is annotated with `@Serializable`.
448448
This requirement extends to PPrint-Multiplatform as well since it relies on `kotlinx-serialization`
449449
to traverse the hierarchy.
450450
451-
#### How do deal with Custom Fields in KMP
451+
## Manual Printing in Kotlin Multiplatform
452+
453+
If you want to print values with a simple and well-defined structure in Kotlin Multiplatform, you can use the the PPrinterManual class.
454+
For example:
455+
```kotlin
456+
data class Person(val name: String, val age: Int)
457+
458+
class CustomPPrinter7 : PPrinterManual<Person>() {
459+
override fun treeify(x: Any?, elementName: String?, escapeUnicode: Boolean, showFieldNames: Boolean): Tree =
460+
when (x) {
461+
is Person -> Tree.Apply("Person", listOf(Tree.KeyValue("name", Tree.Literal(x.name)), Tree.KeyValue("age", Tree.Literal(x.age))).iterator())
462+
else -> super.treeify(x, elementName, escapeUnicode, showFieldNames) // will just use Tree.Literal(x.toString())
463+
}
464+
}
465+
466+
val p = Person("Joe", 42)
467+
println(CustomPPrinter7().invoke(p))
468+
//> Person(name = "Joe", age = 42)
469+
```
470+
471+
Frequently, it will be useful to combine manual printers and automatic printers. For example:
472+
```kotlin
473+
data class PersonFavorite(val name: String, val age: Int, val favoriteColor: Colors) /// See the Sealed Hierarchies section above
474+
475+
class ColorsPrinter(config: PPrinterConfig): PPrinter<Colors>(Colors.serializer(), config)
476+
477+
class CustomPPrinter7(config: PPrinterConfig): PPrinterManual<Any?>(config) {
478+
fun treeifyThis(x: Any?, elementName: String?) =
479+
treeify(x, elementName, config.defaultEscapeUnicode, config.defaultShowFieldNames)
480+
481+
override fun treeify(x: Any?, elementName: String?, escapeUnicode: Boolean, showFieldNames: Boolean): Tree =
482+
when (x) {
483+
is PersonFavorite ->
484+
Tree.Apply(
485+
"PersonFavorite",
486+
iteratorOf(treeifyThis(x.name, "name"), treeifyThis(x.age, "age"), treeifyThis(x.favoriteColor, "favoriteColor")),
487+
elementName
488+
)
489+
is Colors -> ColorsPrinter(config).treeify(x, elementName, escapeUnicode, showFieldNames)
490+
else -> super.treeify(x, elementName, escapeUnicode, showFieldNames)
491+
}
492+
}
493+
494+
val joe = PersonFavorite("Joe", 123, Colors.Custom("FF0000"))
495+
val printer = CustomPPrinter7(PPrinterConfig())
496+
val p = printer(joe)
497+
println(p)
498+
//> PersonFavorite("Joe", 123, Custom(value = "FF0000"))
499+
```
500+
501+
#### How do deal with Custom Fields in Kotlin Multiplatform
452502
453503
In general whenever you have a atom-property i.e. something not generic you can just mark the field as @Contextual
454504
so long as there is a specific case defined for it in `treeifyWith`. However if you are using a type such as

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ allprojects {
2020

2121
allprojects {
2222
group = "io.exoquery"
23-
version = "3.0.0.E"
23+
version = "3.0.0"
2424
}
2525

2626
subprojects {

pprint-kotlin-core/src/commonMain/kotlin/io/exoquery/pprint/Walker.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,29 @@ sealed interface Tree {
1515
/**
1616
* Foo(aa, bbb, cccc)
1717
*/
18-
data class Apply(val prefix: String, val body: Iterator<Tree>, override val elementName: String?): Tree
18+
data class Apply(val prefix: String, val body: Iterator<Tree>, override val elementName: String? = null): Tree
1919

2020
/**
2121
* LHS op RHS
2222
*/
23-
data class Infix(val lhs: Tree, val op: String, val rhs: Tree, override val elementName: String?): Tree
23+
data class Infix(val lhs: Tree, val op: String, val rhs: Tree, override val elementName: String? = null): Tree
2424

2525
/**
2626
* "xyz"
2727
*/
28-
data class Literal(val body: String, override val elementName: String?): Tree{
28+
data class Literal(val body: String, override val elementName: String? = null): Tree{
2929
val hasNewLine = body.any { c -> c == '\n' || c == '\r' }
3030
}
3131

3232
/**
3333
* x = y
3434
*/
35-
data class KeyValue(val key: String, val value: Tree, override val elementName: String?): Tree
35+
data class KeyValue(val key: String, val value: Tree, override val elementName: String? = null): Tree
3636

3737
/**
3838
* xyz
3939
*/
40-
data class Lazy(val body0: (Ctx) -> Iterator<String>, override val elementName: String?): Tree
40+
data class Lazy(val body0: (Ctx) -> Iterator<String>, override val elementName: String? = null): Tree
4141

4242
data class Ctx(
4343
val width: Int,

pprint-kotlin-kmp/src/jvmTest/kotlin/io/exoquery/pprint/KmpExamples.kt

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package io.exoquery.pprint
33
import io.exoquery.kmp.pprint.PPrintSequenceSerializer
44
import io.exoquery.kmp.pprint.PPrinter
55
import io.exoquery.kmp.pprint
6+
import io.exoquery.kmp.pprint.PPrinterManual
67
import kotlinx.serialization.*
78
import java.time.LocalDate
89
import java.time.format.DateTimeFormatter
@@ -168,6 +169,42 @@ fun customPrinter6() {
168169
println(p)
169170
}
170171

172+
@Serializable
173+
sealed interface Colors {
174+
@Serializable object Red : Colors
175+
@Serializable object Green : Colors
176+
@Serializable object Blue : Colors
177+
@Serializable data class Custom(val value: String) : Colors
178+
}
179+
180+
data class PersonFavorite(val name: String, val age: Int, val favoriteColor: Colors) /// See the Sealed Hierarchies section above
181+
182+
class ColorsPrinter(config: PPrinterConfig): PPrinter<Colors>(Colors.serializer(), config)
183+
184+
class CustomPPrinter7(config: PPrinterConfig): PPrinterManual<Any?>(config) {
185+
fun treeifyThis(x: Any?, elementName: String?) =
186+
treeify(x, elementName, config.defaultEscapeUnicode, config.defaultShowFieldNames)
187+
188+
override fun treeify(x: Any?, elementName: String?, escapeUnicode: Boolean, showFieldNames: Boolean): Tree =
189+
when (x) {
190+
is PersonFavorite ->
191+
Tree.Apply(
192+
"PersonFavorite",
193+
iteratorOf(treeifyThis(x.name, "name"), treeifyThis(x.age, "age"), treeifyThis(x.favoriteColor, "favoriteColor")),
194+
elementName
195+
)
196+
is Colors -> ColorsPrinter(config).treeify(x, elementName, escapeUnicode, showFieldNames)
197+
else -> super.treeify(x, elementName, escapeUnicode, showFieldNames)
198+
}
199+
}
200+
201+
fun customPrinter7() {
202+
val joe = PersonFavorite("Joe", 123, Colors.Custom("FF0000"))
203+
val printer = CustomPPrinter7(PPrinterConfig(showGenericForCollections = true))
204+
val p = printer(joe)
205+
println(p)
206+
}
207+
171208
@OptIn(ExperimentalSerializationApi::class)
172209
fun main() {
173210
// showMap()
@@ -180,5 +217,6 @@ fun main() {
180217

181218
// GADT1.gadt()
182219
//GADT2.gadt()
183-
customPrinter6()
220+
//customPrinter6()
221+
customPrinter7()
184222
}

0 commit comments

Comments
 (0)