or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdbuilt-ins.mdcore-serialization.mddescriptors.mdencoding.mdindex.mdmodules.md

modules.mddocs/

0

# Serialization Modules

1

2

The SerializersModule system provides runtime configuration for custom serializers, contextual serialization, and polymorphic type handling. It allows you to register serializers that are resolved at runtime rather than compile time, enabling flexible serialization behavior for external types and polymorphic hierarchies.

3

4

## Capabilities

5

6

### Core Module Classes

7

8

The fundamental classes for building and managing serializers modules.

9

10

```kotlin { .api }

11

/**

12

* A collection of serializers used by ContextualSerializer and PolymorphicSerializer

13

* to override or provide serializers at runtime. Acts as a registry for runtime serializer resolution.

14

*/

15

sealed class SerializersModule {

16

/**

17

* Returns a contextual serializer associated with the given class.

18

* Used for types marked with @Contextual annotation.

19

*/

20

fun <T : Any> getContextual(

21

kClass: KClass<T>,

22

typeArgumentsSerializers: List<KSerializer<*>> = emptyList()

23

): KSerializer<T>?

24

25

/**

26

* Returns a polymorphic serializer for the given base class and actual value.

27

* Used for polymorphic serialization scenarios.

28

*/

29

fun getPolymorphic(

30

baseClass: KClass<Any>,

31

value: Any

32

): SerializationStrategy<Any>?

33

34

/**

35

* Returns a polymorphic deserializer for the given base class and class discriminator.

36

* Used during polymorphic deserialization.

37

*/

38

fun getPolymorphic(

39

baseClass: KClass<Any>,

40

serializedClassName: String?

41

): DeserializationStrategy<out Any>?

42

}

43

44

/**

45

* Builder class for creating SerializersModule using DSL syntax.

46

* Provides methods for registering contextual and polymorphic serializers.

47

*/

48

class SerializersModuleBuilder : SerializersModuleCollector {

49

/**

50

* Builds the final SerializersModule from registered serializers.

51

*/

52

fun build(): SerializersModule

53

}

54

55

/**

56

* Builder for registering polymorphic serializers within the scope of a base class.

57

* Provides type-safe registration of subclass serializers.

58

*/

59

class PolymorphicModuleBuilder<Base : Any> {

60

/**

61

* Register a subclass serializer for polymorphic serialization.

62

*/

63

fun <T : Base> subclass(kClass: KClass<T>, serializer: KSerializer<T>)

64

65

/**

66

* Register a subclass serializer using reified type parameter.

67

*/

68

inline fun <reified T : Base> subclass(serializer: KSerializer<T>)

69

70

/**

71

* Set a default serializer provider for unknown subclasses during serialization.

72

*/

73

fun defaultSerializer(defaultSerializerProvider: (value: Base) -> SerializationStrategy<Base>?)

74

75

/**

76

* Set a default deserializer provider for unknown subclasses during deserialization.

77

*/

78

fun defaultDeserializer(defaultDeserializerProvider: (className: String?) -> DeserializationStrategy<out Base>?)

79

}

80

```

81

82

### Module Builder Functions

83

84

Factory functions for creating SerializersModule instances.

85

86

```kotlin { .api }

87

/**

88

* Creates a SerializersModule using DSL syntax.

89

* The primary way to build modules with multiple serializers.

90

* @param builderAction Lambda to configure the module

91

* @return Configured SerializersModule

92

*/

93

fun SerializersModule(builderAction: SerializersModuleBuilder.() -> Unit): SerializersModule

94

95

/**

96

* Creates a SerializersModule with a single contextual serializer.

97

* @param kClass The class to register a serializer for

98

* @param serializer The serializer to register

99

* @return SerializersModule containing the single registration

100

*/

101

fun <T : Any> serializersModuleOf(kClass: KClass<T>, serializer: KSerializer<T>): SerializersModule

102

103

/**

104

* Creates a SerializersModule with a single contextual serializer using reified type.

105

* @param serializer The serializer to register

106

* @return SerializersModule containing the single registration

107

*/

108

inline fun <reified T : Any> serializersModuleOf(serializer: KSerializer<T>): SerializersModule

109

110

/**

111

* Returns an empty SerializersModule that contains no serializers.

112

* @return Empty SerializersModule instance

113

*/

114

fun EmptySerializersModule(): SerializersModule

115

```

116

117

### Contextual Serialization

118

119

Methods for registering serializers that are resolved based on usage context.

120

121

```kotlin { .api }

122

/**

123

* Register a contextual serializer for the given class.

124

* Used for types that need custom serialization but aren't marked @Serializable.

125

* @param kClass The class to register a serializer for

126

* @param serializer The serializer to use for the class

127

*/

128

fun <T : Any> SerializersModuleBuilder.contextual(kClass: KClass<T>, serializer: KSerializer<T>)

129

130

/**

131

* Register a contextual serializer using reified type parameter.

132

* @param serializer The serializer to use for type T

133

*/

134

inline fun <reified T : Any> SerializersModuleBuilder.contextual(serializer: KSerializer<T>)

135

136

/**

137

* Register a contextual serializer provider for generic classes.

138

* The provider receives type argument serializers and returns a configured serializer.

139

* @param kClass The generic class to register a provider for

140

* @param provider Function that creates serializers based on type arguments

141

*/

142

fun <T : Any> SerializersModuleBuilder.contextual(

143

kClass: KClass<T>,

144

provider: (typeArgumentsSerializers: List<KSerializer<*>>) -> KSerializer<*>

145

)

146

147

/**

148

* Register a contextual serializer provider using reified type parameter.

149

* @param provider Function that creates serializers based on type arguments

150

*/

151

inline fun <reified T : Any> SerializersModuleBuilder.contextual(

152

provider: (typeArgumentsSerializers: List<KSerializer<*>>) -> KSerializer<*>

153

)

154

```

155

156

**Usage Examples:**

157

158

```kotlin

159

import kotlinx.serialization.*

160

import kotlinx.serialization.modules.*

161

import java.time.LocalDate

162

import java.util.UUID

163

164

// Custom serializers for external types

165

object LocalDateSerializer : KSerializer<LocalDate> {

166

override val descriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING)

167

override fun serialize(encoder: Encoder, value: LocalDate) = encoder.encodeString(value.toString())

168

override fun deserialize(decoder: Decoder): LocalDate = LocalDate.parse(decoder.decodeString())

169

}

170

171

object UUIDSerializer : KSerializer<UUID> {

172

override val descriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING)

173

override fun serialize(encoder: Encoder, value: UUID) = encoder.encodeString(value.toString())

174

override fun deserialize(decoder: Decoder): UUID = UUID.fromString(decoder.decodeString())

175

}

176

177

// Create module with contextual serializers

178

val module = SerializersModule {

179

contextual(LocalDate::class, LocalDateSerializer)

180

contextual(UUIDSerializer) // Reified version for UUID

181

182

// Generic contextual serializer

183

contextual(Box::class) { args ->

184

BoxSerializer(args[0]) // args[0] is the serializer for T in Box<T>

185

}

186

}

187

188

// Use with format

189

val json = Json { serializersModule = module }

190

191

@Serializable

192

data class Event(

193

@Contextual val id: UUID,

194

@Contextual val date: LocalDate,

195

val name: String

196

)

197

```

198

199

### Polymorphic Serialization

200

201

Methods for registering serializers for polymorphic type hierarchies.

202

203

```kotlin { .api }

204

/**

205

* Register a polymorphic serializer for a subclass of the base class.

206

* @param baseClass The polymorphic base class

207

* @param actualClass The concrete subclass

208

* @param actualSerializer The serializer for the subclass

209

*/

210

fun <Base : Any, Sub : Base> SerializersModuleBuilder.polymorphic(

211

baseClass: KClass<Base>,

212

actualClass: KClass<Sub>,

213

actualSerializer: KSerializer<Sub>

214

)

215

216

/**

217

* Configure polymorphic serialization for a base class using DSL.

218

* @param baseClass The polymorphic base class

219

* @param builderAction Lambda to configure subclass serializers

220

*/

221

fun <Base : Any> SerializersModuleBuilder.polymorphic(

222

baseClass: KClass<Base>,

223

builderAction: PolymorphicModuleBuilder<Base>.() -> Unit

224

)

225

226

/**

227

* Configure polymorphic serialization using reified type parameter.

228

* @param builderAction Lambda to configure subclass serializers

229

*/

230

inline fun <reified Base : Any> SerializersModuleBuilder.polymorphic(

231

builderAction: PolymorphicModuleBuilder<Base>.() -> Unit

232

)

233

234

/**

235

* Register a default serialization provider for unknown subclasses.

236

* @param baseClass The polymorphic base class

237

* @param defaultSerializerProvider Function to provide serializers for unknown types

238

*/

239

fun <Base : Any> SerializersModuleBuilder.polymorphicDefault(

240

baseClass: KClass<Base>,

241

defaultSerializerProvider: (value: Base) -> SerializationStrategy<Base>?

242

)

243

244

/**

245

* Register a default deserialization provider for unknown subclasses.

246

* @param baseClass The polymorphic base class

247

* @param defaultDeserializerProvider Function to provide deserializers for unknown type names

248

*/

249

fun <Base : Any> SerializersModuleBuilder.polymorphicDefaultDeserializer(

250

baseClass: KClass<Base>,

251

defaultDeserializerProvider: (className: String?) -> DeserializationStrategy<out Base>?

252

)

253

```

254

255

**Usage Examples:**

256

257

```kotlin

258

import kotlinx.serialization.*

259

import kotlinx.serialization.modules.*

260

261

// Polymorphic base interface

262

@Serializable

263

sealed interface Animal {

264

val name: String

265

}

266

267

@Serializable

268

@SerialName("dog")

269

data class Dog(override val name: String, val breed: String) : Animal

270

271

@Serializable

272

@SerialName("cat")

273

data class Cat(override val name: String, val indoor: Boolean) : Animal

274

275

// Register polymorphic serializers

276

val animalModule = SerializersModule {

277

polymorphic(Animal::class) {

278

subclass(Dog::class, Dog.serializer())

279

subclass(Cat::class, Cat.serializer())

280

281

// Default serializer for unknown animals

282

defaultSerializer { animal ->

283

when (animal) {

284

is Dog -> Dog.serializer()

285

is Cat -> Cat.serializer()

286

else -> null

287

}

288

}

289

}

290

}

291

292

// External polymorphic hierarchy (not sealed)

293

abstract class Shape

294

data class Circle(val radius: Double) : Shape()

295

data class Rectangle(val width: Double, val height: Double) : Shape()

296

297

val shapeModule = SerializersModule {

298

polymorphic(Shape::class) {

299

subclass(Circle::class, CircleSerializer)

300

subclass(Rectangle::class, RectangleSerializer)

301

}

302

}

303

```

304

305

### Module Extension Functions

306

307

Functions for combining and manipulating SerializersModule instances.

308

309

```kotlin { .api }

310

/**

311

* Combines two SerializersModule instances, with the right module taking precedence.

312

* @param other The module to combine with this one

313

* @return Combined SerializersModule

314

*/

315

operator fun SerializersModule.plus(other: SerializersModule): SerializersModule

316

317

/**

318

* Combines two SerializersModule instances with explicit overwrite behavior.

319

* The right module overwrites registrations from the left module.

320

* @param other The module that will overwrite this one's registrations

321

* @return Combined SerializersModule with overwrite behavior

322

*/

323

fun SerializersModule.overwriteWith(other: SerializersModule): SerializersModule

324

```

325

326

**Usage Examples:**

327

328

```kotlin

329

val baseModule = SerializersModule {

330

contextual(UUID::class, UUIDSerializer)

331

}

332

333

val extendedModule = SerializersModule {

334

contextual(LocalDate::class, LocalDateSerializer)

335

polymorphic(Animal::class) {

336

subclass(Dog.serializer())

337

subclass(Cat.serializer())

338

}

339

}

340

341

// Combine modules

342

val combinedModule = baseModule + extendedModule

343

344

// Override with explicit behavior

345

val overrideModule = SerializersModule {

346

contextual(UUID::class, AlternativeUUIDSerializer)

347

}

348

val finalModule = baseModule.overwriteWith(overrideModule)

349

```

350

351

### Module Introspection

352

353

Interface for examining the contents of SerializersModule instances.

354

355

```kotlin { .api }

356

/**

357

* Interface that can introspect and accumulate the content of any SerializersModule.

358

* Used for copying or analyzing module configurations.

359

*/

360

interface SerializersModuleCollector {

361

/**

362

* Add a contextual serializer to the collection.

363

*/

364

fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>)

365

366

/**

367

* Add a contextual serializer provider to the collection.

368

*/

369

fun <T : Any> contextual(

370

kClass: KClass<T>,

371

provider: (typeArgumentsSerializers: List<KSerializer<*>>) -> KSerializer<*>

372

)

373

374

/**

375

* Add a polymorphic serializer to the collection.

376

*/

377

fun <Base : Any, Sub : Base> polymorphic(

378

baseClass: KClass<Base>,

379

actualClass: KClass<Sub>,

380

actualSerializer: KSerializer<Sub>

381

)

382

}

383

```

384

385

## Integration with Formats

386

387

SerializersModule is typically used when creating format instances:

388

389

```kotlin

390

import kotlinx.serialization.json.*

391

392

val customModule = SerializersModule {

393

contextual(LocalDate::class, LocalDateSerializer)

394

contextual(UUID::class, UUIDSerializer)

395

}

396

397

val json = Json {

398

serializersModule = customModule

399

// other format configuration

400

}

401

402

// All contextual types are now resolved using the module

403

val event = Event(UUID.randomUUID(), LocalDate.now(), "Conference")

404

val jsonString = json.encodeToString(event)

405

val decoded = json.decodeFromString<Event>(jsonString)

406

```

407

408

## Error Handling

409

410

Common errors when working with SerializersModule:

411

412

- **SerializationException**: Duplicate serializer registration for the same class

413

- **IllegalArgumentException**: Invalid module configurations or missing serializers

414

- **ClassCastException**: Type mismatches in polymorphic deserializer providers