Skip to content

Commit f57737c

Browse files
committed
refactor(gleam): Use a custom deserializer for dependencies
Do not expose the internal `TomlElement` type of the TOML serialization library as part of the `GleamToml` data model by using a custom deserializer for `Dependency` types. Signed-off-by: Sebastian Schuberth <sebastian@doubleopen.org>
1 parent f0e9b9c commit f57737c

2 files changed

Lines changed: 38 additions & 24 deletions

File tree

plugins/package-managers/gleam/src/main/kotlin/Gleam.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ class Gleam internal constructor(
139139
dependencyHandler.setContext(context)
140140

141141
Scope.entries.forEach { scope ->
142-
val dependencies = gleamToml.getScopeDependencies(scope).map { (name, element) ->
143-
DependencyPackageInfo(name, GleamToml.Dependency.fromToml(element))
142+
val dependencies = gleamToml.getScopeDependencies(scope).map { (name, dep) ->
143+
DependencyPackageInfo(name, dep)
144144
}
145145

146146
graphBuilder.addDependencies(project.id, scope.descriptor, dependencies)

plugins/package-managers/gleam/src/main/kotlin/GleamToml.kt

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ package org.ossreviewtoolkit.plugins.packagemanagers.gleam
2121

2222
import java.io.File
2323

24+
import kotlinx.serialization.KSerializer
25+
import kotlinx.serialization.PolymorphicSerializer
2426
import kotlinx.serialization.SerialName
2527
import kotlinx.serialization.Serializable
28+
import kotlinx.serialization.encoding.Decoder
29+
import kotlinx.serialization.encoding.Encoder
2630

2731
import net.peanuuutz.tomlkt.Toml
28-
import net.peanuuutz.tomlkt.TomlElement
32+
import net.peanuuutz.tomlkt.TomlDecoder
2933
import net.peanuuutz.tomlkt.TomlLiteral
3034
import net.peanuuutz.tomlkt.TomlTable
3135
import net.peanuuutz.tomlkt.asTomlLiteral
@@ -64,11 +68,11 @@ internal data class GleamToml(
6468
val target: String? = null,
6569

6670
/** The project dependencies as a map of package names to version constraints or dependency objects. */
67-
val dependencies: Map<String, TomlElement> = emptyMap(),
71+
val dependencies: Map<String, Dependency> = emptyMap(),
6872

6973
/** Development-only dependencies. */
7074
@SerialName("dev-dependencies")
71-
val devDependencies: Map<String, TomlElement> = emptyMap(),
75+
val devDependencies: Map<String, Dependency> = emptyMap(),
7276

7377
/** Links to project resources like homepage, documentation, etc. */
7478
val links: List<Link> = emptyList()
@@ -142,6 +146,7 @@ internal data class GleamToml(
142146
* - A path dependency (object with "path" field)
143147
* - A git dependency (object with "git" field and optional "ref")
144148
*/
149+
@Serializable(DependencySerializer::class)
145150
sealed interface Dependency {
146151
/** A dependency from hex.pm with a version constraint. */
147152
data class Hex(val version: String) : Dependency
@@ -151,29 +156,38 @@ internal data class GleamToml(
151156

152157
/** A git repository dependency. */
153158
data class Git(val url: String, val ref: String? = null) : Dependency
159+
}
160+
}
154161

155-
companion object {
156-
/**
157-
* Parse a TOML element into a Dependency.
158-
*/
159-
fun fromToml(element: TomlElement): Dependency =
160-
when (element) {
161-
is TomlLiteral -> Hex(element.asTomlLiteral().content)
162-
is TomlTable -> {
163-
val table = element.asTomlTable()
164-
when {
165-
"path" in table -> Path(table.getValue("path").asTomlLiteral().content)
166-
"git" in table -> Git(
167-
url = table.getValue("git").asTomlLiteral().content,
168-
ref = table["ref"]?.asTomlLiteral()?.content
169-
)
170-
171-
else -> throw IllegalArgumentException("Unknown dependency format: $element")
172-
}
173-
}
162+
private object DependencySerializer : KSerializer<GleamToml.Dependency> {
163+
override val descriptor = PolymorphicSerializer(GleamToml.Dependency::class).descriptor
164+
165+
/**
166+
* Parse a TOML element into a Dependency.
167+
*/
168+
override fun deserialize(decoder: Decoder): GleamToml.Dependency {
169+
require(decoder is TomlDecoder)
170+
171+
return when (val element = decoder.decodeTomlElement()) {
172+
is TomlLiteral -> GleamToml.Dependency.Hex(element.asTomlLiteral().content)
173+
is TomlTable -> {
174+
val table = element.asTomlTable()
175+
when {
176+
"path" in table -> GleamToml.Dependency.Path(table.getValue("path").asTomlLiteral().content)
177+
"git" in table -> GleamToml.Dependency.Git(
178+
url = table.getValue("git").asTomlLiteral().content,
179+
ref = table["ref"]?.asTomlLiteral()?.content
180+
)
174181

175182
else -> throw IllegalArgumentException("Unknown dependency format: $element")
176183
}
184+
}
185+
186+
else -> throw IllegalArgumentException("Unknown dependency format: $element")
177187
}
178188
}
189+
190+
override fun serialize(encoder: Encoder, value: GleamToml.Dependency) {
191+
throw NotImplementedError("${descriptor.serialName} can only be deserialized.")
192+
}
179193
}

0 commit comments

Comments
 (0)