From d56753eb5de3049e094ed3a612c500c9516600c5 Mon Sep 17 00:00:00 2001 From: nea Date: Fri, 13 Aug 2021 01:04:47 +0200 Subject: tests --- src/jsMain/kotlin/io/Path.kt | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/jsMain/kotlin/io/Path.kt (limited to 'src/jsMain/kotlin/io/Path.kt') diff --git a/src/jsMain/kotlin/io/Path.kt b/src/jsMain/kotlin/io/Path.kt new file mode 100644 index 0000000..8f77203 --- /dev/null +++ b/src/jsMain/kotlin/io/Path.kt @@ -0,0 +1,75 @@ +package io + +sealed interface Path { + val parts: List + fun toAbsolutePath(relativeTo: Absolute): Absolute { + return relativeTo.resolve(this) + } + + fun resolve(path: Path): Path + + companion object { + val root = Absolute(listOf()) + + fun ofShell(string: String, userHome: Absolute): Path = + ofShell(string.split("/"), userHome) + + fun ofShell(vararg parts: String, userHome: Absolute): Path = + ofShell(parts.toList(), userHome) + + fun of(vararg parts: String): Path = + of(parts.toList()) + + fun of(string: String): Path = + of(string.split("/")) + + fun ofShell(parts: List, userHome: Absolute): Path { + if (parts.firstOrNull() == "~") + return userHome.resolve(Relative(parts.subList(1, parts.size).filter { it.isNotEmpty() })) + return of(parts) + } + + fun of(parts: List): Path { + if (parts.isEmpty()) + return root + if (parts[0] == "") // Starts with a / + return Absolute(parts.subList(1, parts.size).filter { it.isNotEmpty() }) + return Relative(parts.filter { it.isNotEmpty() }) + } + } + + data class Relative internal constructor(override val parts: List) : Path { + override fun resolve(path: Path): Path { + if (path is Absolute) return path + return Relative(this.parts + path.parts) + } + } + + data class Absolute internal constructor(override val parts: List) : Path { + override fun resolve(path: Path): Absolute { + if (path is Absolute) return path + return Absolute(this.parts + path.parts) + } + + fun relativize(path: Path): Relative = when (path) { + is Relative -> path + is Absolute -> { + var commonPrefix = true + val partList = mutableListOf() + var returns = 0 + for ((idx, part) in path.parts.withIndex()) { + if (idx < this.parts.size) { + if (this.parts[idx] == part && commonPrefix) { + continue + } else { + commonPrefix = false + returns++ + } + } + partList.add(part) + } + Relative(List(returns) { "" } + partList) + } + } + } +} -- cgit