<commit_before>package io.aconite.utils

private val URL_PARAM_REGEX = Regex("^\\{(?<param>[^/{}]+)}|^(?<text>[^{}]+)")
private val URL_VALIDATION_REGEX = Regex("^(?:\\{[^/{}]+}|[^{}]+)+$")

/**
 * Raises when string passed to [UrlTemplate] is not an url.
 * */
class UrlFormatException(message: String): Exception(message)

/**
 * Converts a [url] to string with one leading slash and without
 * trailing slash.
 * @return converted url string
 */
fun formatUrl(url: String) = '/' + url.trim('/')

/**
 * Class for converting the url-template string to regex for routing.
 * The url can contain parameters (in curly brackets), witch will be
 * converted to the capturing groups. This class supports comparing
 * to order the urls for right routing. For example, this url-templates:
 * ```
 * /baz
 * /baz/{id}
 * /foo/bar
 * /baz/bar
 * ```
 * will be placed in this order:
 * ```
 * /baz/bar
 * /baz/{id}
 * /baz
 * /foo/bar
 * ```
 * so, url `/baz/bar` will be accepted by first template, although it
 * can be accepted by the second template too.
 * @param[url] url-template string
 */
class UrlTemplate(url: String): Comparable<UrlTemplate> {
    private val parts: List<UrlPart>
    private val params: List<String>
    private val regex: Regex

    init {
        val formattedUrl = formatUrl(url)
        validateUrl(formattedUrl)
        val (parts, params) = buildParts(formattedUrl)
        this.parts = parts
        this.params = params
        this.regex = Regex("^" + parts.map { it.toRegex() }.joinToString(""))
    }
<commit_msg>Documentation: add forgotten @throws<commit_after>package io.aconite.utils

private val URL_PARAM_REGEX = Regex("^\\{(?<param>[^/{}]+)}|^(?<text>[^{}]+)")
private val URL_VALIDATION_REGEX = Regex("^(?:\\{[^/{}]+}|[^{}]+)+$")

/**
 * Raises when string passed to [UrlTemplate] is not an url.
 * */
class UrlFormatException(message: String): Exception(message)

/**
 * Converts a [url] to string with one leading slash and without
 * trailing slash.
 * @return converted url string
 */
fun formatUrl(url: String) = '/' + url.trim('/')

/**
 * Class for converting the url-template string to regex for routing.
 * The url can contain parameters (in curly brackets), witch will be
 * converted to the capturing groups. This class supports comparing
 * to order the urls for right routing. For example, this url-templates:
 * ```
 * /baz
 * /baz/{id}
 * /foo/bar
 * /baz/bar
 * ```
 * will be placed in this order:
 * ```
 * /baz/bar
 * /baz/{id}
 * /baz
 * /foo/bar
 * ```
 * so, url `/baz/bar` will be accepted by first template, although it
 * can be accepted by the second template too.
 * @param[url] url-template string
 * @throws[UrlFormatException] if malformed string was passed to constructor as url
 */
class UrlTemplate(url: String): Comparable<UrlTemplate> {
    private val parts: List<UrlPart>
    private val params: List<String>
    private val regex: Regex

    init {
        val formattedUrl = formatUrl(url)
        validateUrl(formattedUrl)
        val (parts, params) = buildParts(formattedUrl)
        this.parts = parts
        this.params = params
        this.regex = Regex("^" + parts.map { it.toRegex() }.joinToString(""))
    }

{'fraction_non_alphanumeric': 0.15129728040012505, 'fraction_numerical': 0.0, 'mean_word_length': 3.4198895027624308, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '918702', 'n_tokens_mistral': 1022, 'n_tokens_neox': 981, 'n_words': 325}