-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: use snakeyaml-engine-kmp for validation
- Loading branch information
Showing
30 changed files
with
130 additions
and
116 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 81 additions & 26 deletions
107
src/jvmMain/kotlin/it/krzeminski/githubactionstyping/parsing/TypesManifestParsing.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,99 @@ | ||
package it.krzeminski.githubactionstyping.parsing | ||
|
||
import com.charleskorn.kaml.AnchorsAndAliases | ||
import com.charleskorn.kaml.EmptyYamlDocumentException | ||
import com.charleskorn.kaml.Yaml | ||
import kotlinx.serialization.SerialName | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.decodeFromString | ||
|
||
@Serializable | ||
import it.krzeminski.snakeyaml.engine.kmp.api.Load | ||
import it.krzeminski.snakeyaml.engine.kmp.api.LoadSettings | ||
import it.krzeminski.snakeyaml.engine.kmp.schema.CoreSchema | ||
|
||
data class TypesManifest( | ||
val inputs: Map<String, ApiItem>? = null, | ||
val outputs: Map<String, ApiItem>? = null, | ||
) | ||
|
||
@Serializable | ||
data class ApiItem( | ||
val type: String? = null, | ||
val name: String? = null, | ||
@SerialName("allowed-values") | ||
val allowedValues: List<String>? = null, | ||
val separator: String? = null, | ||
@SerialName("named-values") | ||
val namedValues: Map<String, String>? = null, | ||
@SerialName("list-item") | ||
val namedValues: Map<String, Int>? = null, | ||
val listItem: ApiItem? = null, | ||
) | ||
|
||
private val myYaml = Yaml( | ||
configuration = Yaml.default.configuration.copy( | ||
strictMode = false, | ||
anchorsAndAliases = AnchorsAndAliases.Permitted(), | ||
) | ||
) | ||
|
||
fun parseTypesManifest(manifestString: String): TypesManifest = | ||
fun parseTypesManifest(manifestString: String): Result<TypesManifest> = | ||
runCatching { | ||
myYaml.decodeFromString<TypesManifest>(manifestString) | ||
}.getOrElse { | ||
if (it is EmptyYamlDocumentException) { | ||
return TypesManifest() | ||
val loadedTypesManifest = Load( | ||
// work-around for https://github.com/krzema12/snakeyaml-engine-kmp/pull/390 | ||
LoadSettings.builder().setSchema(CoreSchema()).build() | ||
).loadOne(manifestString) | ||
|
||
when (loadedTypesManifest) { | ||
null -> TypesManifest() | ||
|
||
is Map<*, *> -> { | ||
TypesManifest( | ||
inputs = loadedTypesManifest.toInputsOrOutputs("inputs"), | ||
outputs = loadedTypesManifest.toInputsOrOutputs("outputs"), | ||
) | ||
} | ||
|
||
else -> throw ValidationException("Types file must be a mapping.") | ||
} | ||
} | ||
|
||
private fun Map<*, *>.toInputsOrOutputs(key: String): Map<String, ApiItem>? = | ||
when (val inputsOrOutputs = this[key]) { | ||
null -> null | ||
|
||
is Map<*, *> -> { | ||
inputsOrOutputs.entries.associate { (key, value) -> key as String to value.toApiItem(key) } | ||
} | ||
throw it | ||
|
||
else -> throw ValidationException("$key must be a mapping.") | ||
} | ||
|
||
private fun Any?.toApiItem(key: String): ApiItem = | ||
when (this) { | ||
null -> ApiItem() | ||
|
||
is Map<*, *> -> { | ||
ApiItem( | ||
type = get("type")?.let { | ||
"$it" | ||
}, | ||
name = get("name")?.let { | ||
"$it" | ||
}, | ||
allowedValues = get("allowed-values")?.let { | ||
if (it !is List<*>) { | ||
throw ValidationException("allowed-values must be a sequence.") | ||
} | ||
it.map { | ||
"$it" | ||
} | ||
}, | ||
separator = get("separator")?.let { | ||
if (it !is String) { | ||
throw ValidationException("separator must be string.") | ||
} | ||
it | ||
}, | ||
namedValues = get("named-values")?.let { | ||
if (it !is Map<*, *>) { | ||
throw ValidationException("named-values must be a mapping.") | ||
} | ||
it.mapKeys { (key, _) -> key as String }.mapValues { (_, value) -> | ||
if (value !is Int) { | ||
throw ValidationException("Named values must be integer.") | ||
} | ||
value | ||
} | ||
}, | ||
listItem = toApiItem("list-item"), | ||
) | ||
} | ||
|
||
else -> throw ValidationException("$key must be a mapping.") | ||
} | ||
|
||
private fun Map<*, *>.toApiItem(key: String): ApiItem? = get(key)?.toApiItem(key) | ||
|
||
internal class ValidationException(override val message: String) : Exception(message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.