Skip to content

Commit bd9bd79

Browse files
committed
add location to JsonValueSource invocations.
to demonstrate more complex invocation locations.
1 parent 265307c commit bd9bd79

File tree

1 file changed

+14
-5
lines changed

1 file changed

+14
-5
lines changed

samples/json/src/main/kotlin/com/github/ajalt/clikt/samples/json/JsonValueSource.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,19 @@ import com.github.ajalt.clikt.core.InvalidFileFormat
55
import com.github.ajalt.clikt.parameters.options.Option
66
import com.github.ajalt.clikt.sources.ValueSource
77
import kotlinx.serialization.SerializationException
8-
import kotlinx.serialization.json.*
8+
import kotlinx.serialization.json.Json
9+
import kotlinx.serialization.json.JsonArray
10+
import kotlinx.serialization.json.JsonElement
11+
import kotlinx.serialization.json.JsonObject
12+
import kotlinx.serialization.json.jsonPrimitive
913
import java.io.File
1014

1115
/**
1216
* A [ValueSource] that uses Kotlin serialization to parse JSON files
1317
*/
1418
class JsonValueSource(
1519
private val root: JsonObject,
20+
private val referencePrefix: String,
1621
) : ValueSource {
1722
override fun getValues(context: Context, option: Option): List<ValueSource.Invocation> {
1823
var cursor: JsonElement? = root
@@ -25,21 +30,25 @@ class JsonValueSource(
2530
if (cursor == null) return emptyList()
2631

2732
try {
33+
val jsonReference = referencePrefix + buildJsonPointer(parts)
2834
// This implementation interprets a list as multiple invocations, but you could also
2935
// implement it as a single invocation with multiple values.
3036
if (cursor is JsonArray) return cursor.map {
31-
ValueSource.Invocation.value(it.jsonPrimitive.content)
37+
ValueSource.Invocation.value(value = it.jsonPrimitive.content, location = jsonReference)
3238
}
33-
return ValueSource.Invocation.just(cursor.jsonPrimitive.content)
39+
return ValueSource.Invocation.just(value = cursor.jsonPrimitive.content, location = jsonReference)
3440
} catch (e: IllegalArgumentException) {
3541
// This implementation skips invalid values, but you could handle them differently.
3642
return emptyList()
3743
}
3844
}
3945

46+
private fun buildJsonPointer(parts: List<String>): String =
47+
parts.joinToString(separator = "/", prefix = "/") { it.replace("~", "~0").replace("/", "~1") }
48+
4049
companion object {
4150
fun from(file: File, requireValid: Boolean = false): JsonValueSource {
42-
if (!file.isFile) return JsonValueSource(JsonObject(emptyMap()))
51+
if (!file.isFile) return JsonValueSource(JsonObject(emptyMap()), referencePrefix = "")
4352

4453
val json = try {
4554
Json.parseToJsonElement(file.readText()) as? JsonObject
@@ -50,7 +59,7 @@ class JsonValueSource(
5059
}
5160
JsonObject(emptyMap())
5261
}
53-
return JsonValueSource(json)
62+
return JsonValueSource(json, referencePrefix = file.invariantSeparatorsPath + "#")
5463
}
5564

5665
fun from(file: String, requireValid: Boolean = false): JsonValueSource {

0 commit comments

Comments
 (0)