Glob.kt
package com.hexagonkt.core.text
import kotlin.IllegalArgumentException
import java.util.regex.PatternSyntaxException
/**
* [TODO](https://github.com/hexagontk/hexagon/issues/271).
*
* @property pattern .
*/
data class Glob(val pattern: String) {
/** [TODO](https://github.com/hexagontk/hexagon/issues/271). */
val regex: Regex =
try {
globToRegex(pattern).toRegex()
}
catch (e: PatternSyntaxException) {
throw IllegalArgumentException("Pattern: '$pattern' is not a valid Glob", e)
}
/**
* [TODO](https://github.com/hexagontk/hexagon/issues/271).
*
* @param text .
* @return .
*/
fun matches(text: String): Boolean =
regex.matches(text)
private fun globToRegex(pattern: String): String {
var escaping = false
var bracesCount = 0
return pattern.toCharArray().joinToString("") { currentChar ->
val globPart = when (currentChar) {
'.', '(', ')', '+', '|', '^', '$', '@', '%' -> """\$currentChar"""
'*' -> if (escaping) """\*""" else ".*"
'?' -> if (escaping) """\?""" else "."
'\\' -> if (escaping) """\\""" else ""
'{' -> if (escaping) """\{""" else "("
'}' -> when {
bracesCount > 0 && !escaping -> ")"
escaping -> """\}"""
else -> "}"
}
',' -> when {
bracesCount > 0 && !escaping -> "|"
escaping -> "\\,"
else -> ","
}
else -> currentChar.toString()
}
if (currentChar == '{' && !escaping)
bracesCount++
if (currentChar == '}' && !escaping && bracesCount > 0)
bracesCount--
escaping = !escaping && currentChar == '\\'
globPart
}
}
}