Skip to content

Commit a0b9d49

Browse files
committed
Support string to enum conversion in convert operation.
1 parent 6ec9043 commit a0b9d49

File tree

4 files changed

+42
-1
lines changed

4 files changed

+42
-1
lines changed

docs/StardustDocs/topics/convert.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ df.convert { dfsOf<String>() }.with { it.toCharArray().toList() }
3434
* `LocalDateTime`
3535
* `LocalDate`
3636
* `LocalTime`
37+
* `Duration`
3738

3839
<!---FUN convertTo-->
3940

@@ -45,3 +46,18 @@ df.convert { weight }.toFloat()
4546
```
4647

4748
<!---END-->
49+
50+
Automatic conversion from `String` into enum class is also supported:
51+
52+
```kotlin
53+
enum class Direction { NORTH, SOUTH, WEST, EAST }
54+
```
55+
56+
<!---FUN convertToEnum-->
57+
58+
```kotlin
59+
dataFrameOf("direction")("NORTH", "WEST")
60+
.convert("direction").to<Direction>()
61+
```
62+
63+
<!---END-->

src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/convert.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ internal fun Any.convertTo(type: KType): Any? {
105105

106106
internal inline fun <T> convert(crossinline converter: (T) -> Any?): TypeConverter = { converter(it as T) }
107107

108+
private enum class DummyEnum
109+
108110
internal fun createConverter(from: KType, to: KType, options: ParserOptions? = null): TypeConverter? {
109111
if (from.arguments.isNotEmpty() || to.arguments.isNotEmpty()) return null
110112
if (from.isMarkedNullable) {
@@ -117,7 +119,11 @@ internal fun createConverter(from: KType, to: KType, options: ParserOptions? = n
117119
if (fromClass == toClass) return { it }
118120

119121
return when {
120-
fromClass == String::class -> Parsers[to.withNullability(false)]?.toConverter(options)
122+
fromClass == String::class -> {
123+
Parsers[to.withNullability(false)]?.toConverter(options)
124+
?: if (toClass.isSubclassOf(Enum::class)) convert<String> { java.lang.Enum.valueOf(toClass.java as Class<DummyEnum>, it) }
125+
else null
126+
}
121127
toClass == String::class -> convert<Any> { it.toString() }
122128
else -> when (fromClass) {
123129
Boolean::class -> when (toClass) {

tests/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/convert.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,11 @@ class ConvertTests {
3333
val df = listOf(Schema(Clock.System.now())).toDataFrame()
3434
df.convert { time }.toLocalDateTime()
3535
}
36+
37+
enum class Value { A, B }
38+
39+
@Test
40+
fun `convert string to enum`() {
41+
columnOf("A", "B").convertTo<Value>() shouldBe columnOf(Value.A, Value.B)
42+
}
3643
}

tests/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,18 @@ class Modify : TestBase() {
7474
// SampleEnd
7575
}
7676

77+
enum class Direction {
78+
NORTH, SOUTH, WEST, EAST
79+
}
80+
81+
@Test
82+
fun convertToEnum() {
83+
// SampleStart
84+
dataFrameOf("direction")("NORTH", "WEST")
85+
.convert("direction").to<Direction>()
86+
// SampleEnd
87+
}
88+
7789
@Test
7890
fun parseAll() {
7991
// SampleStart

0 commit comments

Comments
 (0)