Files
planterette/plt-build/src/main/kotlin/moe/rosa/planterette/hakurei/Filesystem.kt

85 lines
2.5 KiB
Kotlin

package moe.rosa.planterette.hakurei
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import java.nio.file.Path
/**
* AbsolutePath holds a pathname checked to be absolute.
* @constructor checks pathname and returns a new AbsolutePath if pathname is absolute.
*/
@Serializable(with = AbsolutePathSerializer::class)
data class AbsolutePath(val pathname: String, @Transient val path: Path = Path.of(pathname)) {
init {
if(!isAbsolute(pathname)) {
throw AbsolutePathException(pathname)
}
}
operator fun plus(other: String): AbsolutePath {
return AbsolutePath(pathname + other)
}
companion object {
fun isAbsolute(pathname: String): Boolean {
return Path.of(pathname).isAbsolute
}
}
}
object AbsolutePathSerializer : KSerializer<AbsolutePath> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(this::class.qualifiedName!!, PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: AbsolutePath) {
encoder.encodeString(value.pathname)
}
override fun deserialize(decoder: Decoder): AbsolutePath {
val path = decoder.decodeString()
return AbsolutePath(path)
}
}
/**
* AbsolutePathException is returned by @see AbsolutePath() and holds the invalid pathname.
*/
data class AbsolutePathException(val pathname: String) : IllegalArgumentException("Path $pathname is not absolute")
@Serializable sealed interface FilesystemConfig
@Serializable
@SerialName("bind")
data class FSBind(
@SerialName("dst") val target: AbsolutePath? = null,
@SerialName("src") val source: AbsolutePath,
val write: Boolean? = null,
@SerialName("dev") val device: Boolean? = null,
val ensure: Boolean? = null,
val optional: Boolean? = null,
val special: Boolean? = null,
) : FilesystemConfig
@Serializable
@SerialName("ephemeral")
data class FSEphemeral(
@SerialName("dst") val target: AbsolutePath,
val write: Boolean,
val size: Int? = null,
val perm: Int,
) : FilesystemConfig
@Serializable
@SerialName("link")
data class FSLink(
@SerialName("dst") val target: AbsolutePath,
val linkname: String,
val dereference: Boolean,
) : FilesystemConfig
@Serializable
@SerialName("overlay")
data class FSOverlay(
@SerialName("dst") val target: AbsolutePath,
val lower: List<AbsolutePath>,
val upper: AbsolutePath,
val work: AbsolutePath,
) : FilesystemConfig