mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 15:40:28 +08:00
Make SemVersion.Requirement data class
This commit is contained in:
parent
d54f4cd0d9
commit
ce678a75b7
@ -189,7 +189,7 @@ internal object RangeTokenReader {
|
||||
}
|
||||
}
|
||||
|
||||
fun parse(source: String, token: Token): SemVersion.Requirement {
|
||||
fun parse(source: String, token: Token): RequirementInternal {
|
||||
return when (token) {
|
||||
is Token.Group -> {
|
||||
if (token.values.size == 1) {
|
||||
@ -206,7 +206,7 @@ internal object RangeTokenReader {
|
||||
}.map { parse(source, it) }.toList()
|
||||
when (logic.first()) {
|
||||
TokenType.OR -> {
|
||||
return object : SemVersion.Requirement {
|
||||
return object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean {
|
||||
rules.forEach { if (it.test(version)) return true }
|
||||
return false
|
||||
@ -214,7 +214,7 @@ internal object RangeTokenReader {
|
||||
}
|
||||
}
|
||||
TokenType.AND -> {
|
||||
return object : SemVersion.Requirement {
|
||||
return object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean {
|
||||
rules.forEach { if (!it.test(version)) return false }
|
||||
return true
|
||||
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||
*
|
||||
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
|
||||
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found through the following link.
|
||||
*
|
||||
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
package net.mamoe.mirai.console.internal.util.semver
|
||||
|
||||
import net.mamoe.mirai.console.util.SemVersion
|
||||
|
||||
internal interface RequirementInternal {
|
||||
fun test(version: SemVersion): Boolean
|
||||
}
|
@ -75,11 +75,11 @@ internal object SemVersionInternal {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
internal fun parseRule(rule: String): SemVersion.Requirement {
|
||||
internal fun parseRule(rule: String): RequirementInternal {
|
||||
val trimmed = rule.trim()
|
||||
if (directVersion.matches(trimmed)) {
|
||||
val parsed = SemVersion.invoke(trimmed)
|
||||
return object : SemVersion.Requirement {
|
||||
return object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version.compareTo(parsed) == 0
|
||||
}
|
||||
}
|
||||
@ -89,7 +89,7 @@ internal object SemVersionInternal {
|
||||
.replace("x", ".+") +
|
||||
"$"
|
||||
).toRegex()
|
||||
return object : SemVersion.Requirement {
|
||||
return object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = regex.matches(version.toString())
|
||||
}
|
||||
}
|
||||
@ -120,7 +120,7 @@ internal object SemVersionInternal {
|
||||
'(', ')' -> ({ it < end })
|
||||
else -> throw AssertionError()
|
||||
}
|
||||
return object : SemVersion.Requirement {
|
||||
return object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = a(version) && b(version)
|
||||
}
|
||||
}
|
||||
@ -129,32 +129,32 @@ internal object SemVersionInternal {
|
||||
val version1 = SemVersion.invoke(result.groupValues[8])
|
||||
return when (operator) {
|
||||
">=" -> {
|
||||
object : SemVersion.Requirement {
|
||||
object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version >= version1
|
||||
}
|
||||
}
|
||||
">" -> {
|
||||
object : SemVersion.Requirement {
|
||||
object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version > version1
|
||||
}
|
||||
}
|
||||
"<=" -> {
|
||||
object : SemVersion.Requirement {
|
||||
object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version <= version1
|
||||
}
|
||||
}
|
||||
"<" -> {
|
||||
object : SemVersion.Requirement {
|
||||
object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version < version1
|
||||
}
|
||||
}
|
||||
"=" -> {
|
||||
object : SemVersion.Requirement {
|
||||
object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version.compareTo(version1) == 0
|
||||
}
|
||||
}
|
||||
"!=" -> {
|
||||
object : SemVersion.Requirement {
|
||||
object : RequirementInternal {
|
||||
override fun test(version: SemVersion): Boolean = version.compareTo(version1) != 0
|
||||
}
|
||||
}
|
||||
@ -164,15 +164,9 @@ internal object SemVersionInternal {
|
||||
throw IllegalArgumentException("Cannot parse $rule")
|
||||
}
|
||||
|
||||
private fun SemVersion.Requirement.withRule(rule: String): SemVersion.Requirement {
|
||||
return object : SemVersion.Requirement {
|
||||
override fun test(version: SemVersion): Boolean = this@withRule.test(version)
|
||||
override fun toString(): String = rule
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseRangeRequirement(requirement: String): SemVersion.Requirement {
|
||||
fun parseRangeRequirement(requirement: String): RequirementInternal {
|
||||
if (requirement.isBlank()) {
|
||||
throw IllegalArgumentException("Invalid requirement: Empty requirement rule.")
|
||||
}
|
||||
@ -180,7 +174,7 @@ internal object SemVersionInternal {
|
||||
val collected = RangeTokenReader.collect(requirement, tokens.iterator(), true)
|
||||
RangeTokenReader.check(requirement, collected.iterator(), null)
|
||||
return kotlin.runCatching {
|
||||
RangeTokenReader.parse(requirement, RangeTokenReader.Token.Group(collected, 0)).withRule(requirement)
|
||||
RangeTokenReader.parse(requirement, RangeTokenReader.Token.Group(collected, 0))
|
||||
}.onFailure { error ->
|
||||
throw IllegalArgumentException("Exception in parsing $requirement\n\n" + buildString {
|
||||
collected.forEach { dump("", it) }
|
||||
|
@ -81,9 +81,33 @@ internal constructor(
|
||||
* 一条依赖规则
|
||||
* @see [parseRangeRequirement]
|
||||
*/
|
||||
public interface Requirement {
|
||||
@Serializable(Requirement.RequirementAsStringSerializer::class)
|
||||
public data class Requirement internal constructor(
|
||||
/**
|
||||
* 规则的字符串表示方式
|
||||
*
|
||||
* @see [SemVersion.parseRangeRequirement]
|
||||
*/
|
||||
val rule: String
|
||||
) {
|
||||
@Transient
|
||||
private val impl = SemVersionInternal.parseRangeRequirement(rule)
|
||||
|
||||
/** 在 [version] 满足此要求时返回 true */
|
||||
public fun test(version: SemVersion): Boolean
|
||||
public fun test(version: SemVersion): Boolean {
|
||||
return impl.test(version)
|
||||
}
|
||||
|
||||
public object RequirementAsStringSerializer : KSerializer<Requirement> by String.serializer().map(
|
||||
serializer = { it.rule },
|
||||
deserializer = { parseRangeRequirement(it) }
|
||||
)
|
||||
|
||||
public companion object {
|
||||
@JvmSynthetic
|
||||
public operator fun invoke(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Requirement =
|
||||
parseRangeRequirement(requirement)
|
||||
}
|
||||
}
|
||||
|
||||
public object SemVersionAsStringSerializer : KSerializer<SemVersion> by String.serializer().map(
|
||||
@ -149,7 +173,7 @@ internal constructor(
|
||||
@JvmStatic
|
||||
@Throws(IllegalArgumentException::class)
|
||||
public fun parseRangeRequirement(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Requirement =
|
||||
SemVersionInternal.parseRangeRequirement(requirement)
|
||||
Requirement(requirement)
|
||||
|
||||
/** @see [Requirement.test] */
|
||||
@JvmStatic
|
||||
|
@ -16,6 +16,7 @@ package net.mamoe.mirai.console.util
|
||||
|
||||
import net.mamoe.mirai.console.util.SemVersion.Companion.test
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertFails
|
||||
|
||||
internal class TestSemVersion {
|
||||
@Test
|
||||
@ -50,9 +51,9 @@ internal class TestSemVersion {
|
||||
}
|
||||
|
||||
fun assertInvalid(requirement: String) {
|
||||
kotlin.runCatching {
|
||||
assertFails(requirement) {
|
||||
SemVersion.parseRangeRequirement(requirement)
|
||||
}.onSuccess { assert(false) { requirement } }
|
||||
}
|
||||
}
|
||||
|
||||
fun SemVersion.Requirement.assertFalse(version: String): SemVersion.Requirement {
|
||||
|
Loading…
Reference in New Issue
Block a user