/** * Different case matchers * * @see Examples of multiple word identifier formats LowerFlatCaseMatcher() containsAll("upper", "flat") -> UpperFlatCaseMatcher() containsExcluding("camel", setOf("upper", "snake")) || containsAll("lower", "camel") || containsAll("dromedary") -> LowerCamelCaseMatcher() containsAll("upper", "camel") || containsAll("pascal") || containsAll("studly") -> UpperCamelCaseMatcher() containsExcluding("snake", setOf("upper", "screaming", "camel")) || containsAll("lower", "snake") || containsAll("pothole") -> SnakeCaseMatcher() containsAll("upper", "snake") || containsAll("screaming", "snake") || containsAll("macro") || containsAll("constant") -> ScreamingSnakeCaseMatcher() containsAll("camel", "snake") -> CamelSnakeCaseMatcher() containsExcluding("kebab", setOf("upper", "screaming")) || containsAll("lower", "kebab") || containsAll("dash") || containsAll("lisp") -> KebabCaseMatcher() containsAll("upper", "kebab") || containsAll("screaming", "kebab") || containsAll("cobol") -> ScreamingKebabCaseMatcher() containsAll("train") -> TrainCaseMatcher() else -> null } } } /** * Test if current string contains only given word and does not have excluded words ignoring case */ private fun String.containsExcluding(include: String, exclude: Set): Boolean { exclude.forEach { tag -> if (this.contains(other = tag, ignoreCase = true)) { return false } } return this.contains(other = include, ignoreCase = true) } /** * Test if current string contains all given words ignoring case */ private fun String.containsAll(vararg tags: String): Boolean { if (tags.isEmpty()) { return false } return tags.toSet().all { tag -> this.contains(other = tag, ignoreCase = true) } } } } /** * Represents matching for flat case, e.g. 'flatcase' * * Can be also referred as: lower flat case */ class LowerFlatCaseMatcher : CaseMatcher(Regex("[a-z0-9]+")) /** * Represents matching for upper flat case, e.g. 'UPPERFLATCASE' */ class UpperFlatCaseMatcher : CaseMatcher(Regex("[A-Z0-9]+")) /** * Represents matching for camel case, e.g. 'camelCase' * * Can be also referred as: lower camel case, dromedary case */ class LowerCamelCaseMatcher : CaseMatcher(Regex("[a-z]+(?:[A-Z0-9]+[a-z0-9]+[A-Za-z0-9]*)*")) /** * Represents matching for upper camel case, e.g. 'UpperCamelCase' * * Can be also referred as: pascal case, studly case */ class UpperCamelCaseMatcher : CaseMatcher(Regex("(?:[A-Z][a-z0-9]+)(?:[A-Z]+[a-z0-9]*)*")) /** * Represents matching for snake case, e.g. 'snake_case' * * Can be also referred as: lower snake case, pothole case */ class SnakeCaseMatcher : CaseMatcher(Regex("[a-z0-9]+(?:_[a-z0-9]+)*")) /** * Represents matching for screaming snake case, e.g. 'SCREAMING_SNAKE_CASE' * * Can be also referred as: upper snake case, macro case, constant case */ class ScreamingSnakeCaseMatcher : CaseMatcher(Regex("[A-Z0-9]+(?:_[A-Z0-9]+)*")) /** * Represents matching for camel snake case, e.g. 'Camel_Snake_Case' */ class CamelSnakeCaseMatcher : CaseMatcher(Regex("[A-Z][a-z0-9]+(?:_[A-Z]+[a-z0-9]*)*")) /** * Represents matching for kebab case, e.g. 'kebab-case' * * Can be also referred as: lower kebab case, dash case, lisp case */ class KebabCaseMatcher : CaseMatcher(Regex("[a-z0-9]+(?:-[a-z0-9]+)*")) /** * Represents matching for screaming kebab case, e.g. 'SCREAMING-KEBAB-CASE' * * Can be also referred as: upper kebab case, cobol case */ class ScreamingKebabCaseMatcher : CaseMatcher(Regex("[A-Z0-9]+(?:-[A-Z0-9]+)*")) /** * Represents matching for train case, e.g. 'Train-Case' */ class TrainCaseMatcher : CaseMatcher(Regex("[A-Z][a-z0-9]+(?:-[A-Z]+[a-z0-9]*)*")) /** * Represents matching for custom regular expressions */ class CustomMatcher(regex: Regex) : CaseMatcher(regex)