Skip to content

Commit

Permalink
jackson wrapper and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
albertlatacz committed Jan 3, 2024
1 parent aec1d4f commit ec9e99b
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 41 deletions.
19 changes: 18 additions & 1 deletion lens4k/src/main/kotlin/dev/forkhandles/lens/AbstractWrapper.kt
Original file line number Diff line number Diff line change
@@ -1,2 +1,19 @@
package dev.forkhandles.lens
package dev.forkhandles.lens

@Suppress("UNCHECKED_CAST")
abstract class AbstractWrapper<CONTENT>(
private val contents: CONTENT,
existsFn: (CONTENT, String) -> Boolean,
getFn: (CONTENT, String) -> Any?
) {
private val exists: AbstractWrapper<CONTENT>.(String) -> Boolean = { existsFn(contents, it) }
private val get: AbstractWrapper<CONTENT>.(String) -> Any? = { getFn(contents, it) }

inner class Field<OUT> : LensProp<AbstractWrapper<CONTENT>, OUT>(exists, get)

inner class ListField<IN : Any, OUT>(mapFn: (IN) -> OUT) :
LensProp<AbstractWrapper<CONTENT>, List<OUT>>(exists, { (get(it) as List<IN>).map(mapFn) })

inner class ObjectField<OUT : AbstractWrapper<CONTENT>>(mapFn: (CONTENT) -> OUT) :
LensProp<AbstractWrapper<CONTENT>, OUT>(exists, { mapFn(get(it) as CONTENT) })
}
28 changes: 27 additions & 1 deletion lens4k/src/main/kotlin/dev/forkhandles/lens/JacksonWrapper.kt
Original file line number Diff line number Diff line change
@@ -1,2 +1,28 @@
package dev.forkhandles.lens
package dev.forkhandles.lens

import com.fasterxml.jackson.databind.JsonNode
import com.fasterxml.jackson.databind.node.*

abstract class JacksonWrapper(node: JsonNode) :
AbstractWrapper<JsonNode>(
node,
{ content, it -> content.has(it) },
{ content, it -> content[it]?.let(::asValue) }
) {

companion object {
private fun asValue(jsonNode: JsonNode): Any? = when (jsonNode) {
is BooleanNode -> jsonNode.booleanValue()
is IntNode -> jsonNode.intValue()
is LongNode -> jsonNode.longValue()
is DecimalNode -> jsonNode.decimalValue()
is DoubleNode -> jsonNode.doubleValue()
is TextNode -> jsonNode.textValue()
is ArrayNode -> jsonNode.map { asValue(it) }
is ObjectNode -> jsonNode
is NullNode -> null
else -> error("Invalid node type $jsonNode")
}

}
}
25 changes: 2 additions & 23 deletions lens4k/src/main/kotlin/dev/forkhandles/lens/MapWrapper.kt
Original file line number Diff line number Diff line change
@@ -1,27 +1,6 @@
package dev.forkhandles.lens

import com.fasterxml.jackson.databind.JsonNode

@Suppress("UNCHECKED_CAST")
abstract class AbstractWrapper<CONTENT>(
private val contents: CONTENT,
existsFn: CONTENT.(String) -> Boolean,
getFn: CONTENT.(String) -> Any?
) {
private val exists: AbstractWrapper<CONTENT>.(String) -> Boolean = { contents.existsFn(it) }
private val get: AbstractWrapper<CONTENT>.(String) -> Any? = { contents.getFn(it) }

inner class Field<OUT> : LensProp<AbstractWrapper<CONTENT>, OUT>(exists, get)

inner class ListField<IN : Any, OUT>(mapFn: (IN) -> OUT) :
LensProp<AbstractWrapper<CONTENT>, List<OUT>>(exists, { (get(it) as List<IN>).map(mapFn) })

inner class ObjectField<OUT : AbstractWrapper<CONTENT>>(mapFn: (CONTENT) -> OUT) :
LensProp<AbstractWrapper<CONTENT>, OUT>(exists, { mapFn(get(it) as CONTENT) })
}

abstract class MapWrapper(map: Map<String, Any?>) :
AbstractWrapper<Map<String, Any?>>(map, { map.containsKey(it) }, { map[it] })
AbstractWrapper<Map<String, Any?>>(map, { content, it -> content.containsKey(it) }, { content, it -> content[it] })


abstract class JacksonWrapper(node: JsonNode) :
AbstractWrapper<JsonNode>(node, { node.has(it) }, { node[it] })
34 changes: 18 additions & 16 deletions lens4k/src/test/kotlin/dev/forkhandles/lens/JacksonWrapperTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,26 @@ class JacksonWrapperTest {

@Test
fun `can get values from properties`() {
val map = mapOf(
"stringField" to "string",
"booleanField" to true,
"intField" to 123,
"longField" to Long.MAX_VALUE,
"decimalField" to 1.1234,
"notAStringField" to 123,
"listField" to listOf(
mapOf("stringField" to "string1"),
mapOf("stringField" to "string2"),
),
"listField2" to listOf("string1", "string2"),
"objectField" to mapOf(
"stringField" to "string"
)
)

val mapBacked = NodeBacked(
ObjectMapper().valueToTree(
mapOf(
"stringField" to "string",
"booleanField" to true,
"intField" to 123,
"longField" to Long.MAX_VALUE,
"decimalField" to 1.1234,
"notAStringField" to 123,
"listField" to listOf(
mapOf("stringField" to "string1"),
mapOf("stringField" to "string2"),
),
"listField2" to listOf("string1", "string2"),
"objectField" to mapOf(
"stringField" to "string"
)
)
map
)
)

Expand Down

0 comments on commit ec9e99b

Please sign in to comment.