0
# Data Conversion
1
2
Data conversion service for serializing and deserializing types to/from string lists. Provides type-safe conversion with support for custom converters and built-in primitive type handling.
3
4
## Capabilities
5
6
### ConversionService Interface
7
8
Base interface for data conversion operations between values and string lists.
9
10
```kotlin { .api }
11
/**
12
* Data conversion service that does serialization and deserialization to/from list of strings
13
*/
14
interface ConversionService {
15
/** Deserialize values to an instance of type */
16
fun fromValues(values: List<String>, type: TypeInfo): Any?
17
18
/** Serialize a value to values list */
19
fun toValues(value: Any?): List<String>
20
}
21
```
22
23
**Usage Examples:**
24
25
```kotlin
26
import io.ktor.util.converters.*
27
import io.ktor.util.reflect.*
28
29
// Use default conversion service
30
val service: ConversionService = DefaultConversionService
31
32
// Convert from strings to values
33
val intValue = service.fromValues(listOf("42"), typeInfo<Int>()) as Int
34
val stringList = service.fromValues(listOf("hello", "world"), typeInfo<List<String>>()) as List<String>
35
36
// Convert values to strings
37
val intStrings = service.toValues(42) // ["42"]
38
val listStrings = service.toValues(listOf("hello", "world")) // ["hello", "world"]
39
```
40
41
### DefaultConversionService
42
43
Built-in conversion service supporting primitive types, collections, and platform-specific conversions.
44
45
```kotlin { .api }
46
/**
47
* The default conversion service that supports only basic types and enums
48
*/
49
object DefaultConversionService : ConversionService {
50
override fun fromValues(values: List<String>, type: TypeInfo): Any?
51
override fun toValues(value: Any?): List<String>
52
53
/** Convert single string value to specific type */
54
fun fromValue(value: String, klass: KClass<*>): Any
55
}
56
```
57
58
**Supported Types:**
59
- Primitive types: `Int`, `Float`, `Double`, `Long`, `Short`, `Char`, `Boolean`, `String`
60
- Collections: `List<T>`, `MutableList<T>` where T is a supported type
61
- Iterable types for serialization
62
- Platform-specific types via expect/actual pattern
63
64
**Usage Examples:**
65
66
```kotlin
67
import io.ktor.util.converters.*
68
import io.ktor.util.reflect.*
69
70
// Basic type conversions
71
val intValue = DefaultConversionService.fromValue("42", Int::class) // 42
72
val boolValue = DefaultConversionService.fromValue("true", Boolean::class) // true
73
val floatValue = DefaultConversionService.fromValue("3.14", Float::class) // 3.14f
74
75
// List conversions
76
val numbers = DefaultConversionService.fromValues(
77
listOf("1", "2", "3"),
78
typeInfo<List<Int>>()
79
) as List<Int> // [1, 2, 3]
80
81
// Serialization
82
val intStrings = DefaultConversionService.toValues(123) // ["123"]
83
val listStrings = DefaultConversionService.toValues(listOf(1, 2, 3)) // ["1", "2", "3"]
84
```
85
86
### DataConversion Class
87
88
Configurable conversion service with support for custom type converters.
89
90
```kotlin { .api }
91
/**
92
* Data conversion plugin to serialize and deserialize types using converters registry
93
*/
94
class DataConversion(configuration: Configuration) : ConversionService {
95
override fun fromValues(values: List<String>, type: TypeInfo): Any?
96
override fun toValues(value: Any?): List<String>
97
98
/**
99
* Data conversion service configuration
100
*/
101
class Configuration {
102
/** Register a converter for type */
103
fun convert(type: KClass<*>, convertor: ConversionService)
104
105
/** Register and configure converter for type */
106
fun <T : Any> convert(type: KType, configure: DelegatingConversionService.Configuration<T>.() -> Unit)
107
108
/** Register and configure converter for reified type */
109
inline fun <reified T : Any> convert(
110
noinline configure: DelegatingConversionService.Configuration<T>.() -> Unit
111
)
112
}
113
}
114
```
115
116
**Usage Examples:**
117
118
```kotlin
119
import io.ktor.util.converters.*
120
import java.time.LocalDate
121
import java.time.format.DateTimeFormatter
122
123
// Configure data conversion with custom converters
124
val dataConversion = DataConversion(DataConversion.Configuration().apply {
125
// Register converter for LocalDate
126
convert<LocalDate> {
127
decode { values ->
128
LocalDate.parse(values.single(), DateTimeFormatter.ISO_LOCAL_DATE)
129
}
130
encode { value ->
131
listOf(value.format(DateTimeFormatter.ISO_LOCAL_DATE))
132
}
133
}
134
135
// Register converter for custom class
136
convert<User> {
137
decode { values ->
138
val parts = values.single().split(":")
139
User(parts[0], parts[1].toInt())
140
}
141
encode { user ->
142
listOf("${user.name}:${user.age}")
143
}
144
}
145
})
146
147
// Use configured conversion
148
data class User(val name: String, val age: Int)
149
150
val user = User("Alice", 30)
151
val serialized = dataConversion.toValues(user) // ["Alice:30"]
152
val deserialized = dataConversion.fromValues(serialized, typeInfo<User>()) as User
153
```
154
155
### DelegatingConversionService
156
157
Implementation that delegates conversion operations to custom encoder/decoder functions.
158
159
```kotlin { .api }
160
/**
161
* Implementation of ConversionService that delegates fromValues and toValues to decoder and encoder
162
*/
163
class DelegatingConversionService(
164
private val klass: KClass<*>,
165
private val decoder: ((values: List<String>) -> Any?)?,
166
private val encoder: ((value: Any?) -> List<String>)?,
167
) : ConversionService {
168
169
override fun fromValues(values: List<String>, type: TypeInfo): Any?
170
override fun toValues(value: Any?): List<String>
171
172
/**
173
* Custom converter builder to be used in DataConversion.Configuration
174
*/
175
class Configuration<T : Any> {
176
/** Configure decoder function */
177
fun decode(converter: (values: List<String>) -> T)
178
179
/** Configure encoder function */
180
fun encode(converter: (value: T) -> List<String>)
181
}
182
}
183
```
184
185
**Usage Examples:**
186
187
```kotlin
188
import io.ktor.util.converters.*
189
import java.util.UUID
190
191
// Create custom delegating service for UUID
192
val uuidService = DelegatingConversionService(
193
klass = UUID::class,
194
decoder = { values -> UUID.fromString(values.single()) },
195
encoder = { value -> listOf(value.toString()) }
196
)
197
198
// Use the service
199
val uuid = UUID.randomUUID()
200
val serialized = uuidService.toValues(uuid) // [uuid string]
201
val deserialized = uuidService.fromValues(serialized, typeInfo<UUID>()) as UUID
202
```
203
204
### Exception Handling
205
206
```kotlin { .api }
207
/**
208
* Thrown when failed to convert value
209
*/
210
open class DataConversionException(message: String = "Invalid data format") : Exception
211
```
212
213
**Usage Examples:**
214
215
```kotlin
216
import io.ktor.util.converters.*
217
218
try {
219
// This will throw DataConversionException for unsupported types
220
DefaultConversionService.fromValue("invalid", CustomClass::class)
221
} catch (e: DataConversionException) {
222
println("Conversion failed: ${e.message}")
223
}
224
225
try {
226
// This will throw for invalid format
227
DefaultConversionService.fromValue("not-a-number", Int::class)
228
} catch (e: NumberFormatException) {
229
println("Invalid number format: ${e.message}")
230
}
231
```
232
233
## Implementation Notes
234
235
- **Platform Support**: ConversionService interface is available on all platforms (Common)
236
- **Expect/Actual Pattern**: Platform-specific converters are handled via expect/actual functions
237
- **Type Safety**: Uses TypeInfo and reflection for type-safe conversions
238
- **Extensibility**: Supports custom converters through DataConversion configuration
239
- **Built-in Types**: DefaultConversionService handles all Kotlin primitive types and basic collections
240
- **Error Handling**: Throws DataConversionException for unsupported types and conversion failures