Skip to content

Commit

Permalink
CellConversionException
Browse files Browse the repository at this point in the history
  • Loading branch information
Kopilov committed Nov 22, 2022
1 parent b427eae commit 89c30e7
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.jetbrains.kotlinx.dataframe.exceptions

import kotlin.reflect.KType

public class CellConversionException(
value: Any?,
from: KType,
to: KType,
public val column: String,
public val row: Int?,
override val cause: Throwable?
) : TypeConversionException(value, from, to) {
override val message: String
get() = "${super.message} in column $column, row $row"
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.jetbrains.kotlinx.dataframe.exceptions

import kotlin.reflect.*
import kotlin.reflect.KType

public class TypeConversionException(public val value: Any?, public val from: KType, public val to: KType) : RuntimeException() {
public open class TypeConversionException(public val value: Any?, public val from: KType, public val to: KType) : RuntimeException() {

override val message: String
get() = "Failed to convert '$value' from $from to $to"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.jetbrains.kotlinx.dataframe.api.to
import org.jetbrains.kotlinx.dataframe.columns.values
import org.jetbrains.kotlinx.dataframe.dataTypes.IFRAME
import org.jetbrains.kotlinx.dataframe.dataTypes.IMG
import org.jetbrains.kotlinx.dataframe.exceptions.CellConversionException
import org.jetbrains.kotlinx.dataframe.exceptions.TypeConversionException
import org.jetbrains.kotlinx.dataframe.exceptions.TypeConverterNotFoundException
import org.jetbrains.kotlinx.dataframe.impl.columns.DataColumnInternal
Expand Down Expand Up @@ -79,31 +80,50 @@ internal fun AnyCol.convertToTypeImpl(to: KType): AnyCol {
else -> throw TypeConversionException(null, from, to)
}

return when {
from == to -> this
from.isSubtypeOf(to) -> (this as DataColumnInternal<*>).changeType(to.withNullability(hasNulls()))
else -> when (val converter = getConverter(from, to, ParserOptions(locale = Locale.getDefault()))) {
null -> when (from.classifier) {
Any::class, Number::class, java.io.Serializable::class -> {
fun applyConverter(converter: TypeConverter): AnyCol {
var currentRow = 0
try {
val values = values.mapIndexed { row, value ->
currentRow = row
value?.let { converter(value) }.checkNulls()
}
return DataColumn.createValueColumn(name, values, to.withNullability(nullsFound))
} catch (e: TypeConversionException) {
throw CellConversionException(e.value, e.from, e.to, this.name(), currentRow, e)
}
}

fun convertPerCell(): AnyCol {
var currentRow = 0
try {
return when (from.classifier) {
Any::class, Comparable::class, Number::class, java.io.Serializable::class -> {
// find converter for every value
val values = values.map {
it?.let {
val values = values.mapIndexed { row, value ->
currentRow = row
value?.let {
val clazz = it.javaClass.kotlin
val type = clazz.createStarProjectedType(false)
val converter = getConverter(type, to, ParserOptions(locale = Locale.getDefault())) ?: throw TypeConverterNotFoundException(from, to)
val converter = getConverter(type, to, ParserOptions(locale = Locale.getDefault()))
?: throw TypeConverterNotFoundException(from, to)
converter(it)
}.checkNulls()
}
DataColumn.createValueColumn(name, values, to.withNullability(nullsFound))
}
else -> throw TypeConverterNotFoundException(from, to)
}
else -> {
val values = values.map {
it?.let { converter(it) }.checkNulls()
}
DataColumn.createValueColumn(name, values, to.withNullability(nullsFound))
}
} catch (e: TypeConversionException) {
throw CellConversionException(e.value, e.from, e.to, this.name(), currentRow, e)
}
}

return when {
from == to -> this
from.isSubtypeOf(to) -> (this as DataColumnInternal<*>).changeType(to.withNullability(hasNulls()))
else -> when (val converter = getConverter(from, to, ParserOptions(locale = Locale.getDefault()))) {
null -> convertPerCell()
else -> applyConverter(converter)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import kotlinx.datetime.Instant
import org.jetbrains.kotlinx.dataframe.DataColumn
import org.jetbrains.kotlinx.dataframe.DataFrame
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
import org.jetbrains.kotlinx.dataframe.exceptions.CellConversionException
import org.jetbrains.kotlinx.dataframe.exceptions.TypeConversionException
import org.jetbrains.kotlinx.dataframe.exceptions.TypeConverterNotFoundException
import org.jetbrains.kotlinx.dataframe.hasNulls
Expand Down Expand Up @@ -80,6 +81,10 @@ class ConvertTests {
columnOf("a").convertTo<IntClass>()
}

shouldThrow<CellConversionException> {
columnOf("1", "10", "a").convertTo<IntClass>()
}.row shouldBe 2

shouldThrow<TypeConverterNotFoundException> {
columnOf(EnumClass.A).convertTo<IntClass>()
}
Expand Down

0 comments on commit 89c30e7

Please sign in to comment.