aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/utilities/Uri.kt
blob: 7e6b3fbefed1d23b70aebb3076ab51bb4b5a22ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
 * Copyright 2014-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package org.jetbrains.dokka.utilities

import org.jetbrains.dokka.InternalDokkaApi
import java.net.URI

@InternalDokkaApi
@Deprecated("Deprecated for removal") // Unused in Dokka
public fun URI.relativeTo(uri: URI): URI {
    // Normalize paths to remove . and .. segments
    val base = uri.normalize()
    val child = this.normalize()

    fun StringBuilder.appendRelativePath() {
        // Split paths into segments
        var bParts = base.path.split('/').dropLastWhile { it.isEmpty() }
        val cParts = child.path.split('/').dropLastWhile { it.isEmpty() }

        // Discard trailing segment of base path
        if (bParts.isNotEmpty() && !base.path.endsWith("/")) {
            bParts = bParts.dropLast(1)
        }

        // Compute common prefix
        val commonPartsSize = bParts.zip(cParts).takeWhile { (basePart, childPart) -> basePart == childPart }.count()
        bParts.drop(commonPartsSize).joinTo(this, separator = "") { "../" }
        cParts.drop(commonPartsSize).joinTo(this, separator = "/")
    }

    return URI.create(buildString {
        if (base.path != child.path) {
            appendRelativePath()
        }
        child.rawQuery?.let {
            append("?")
            append(it)
        }
        child.rawFragment?.let {
            append("#")
            append(it)
        }
    })
}