mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-27 17:00:14 +08:00
Review SemVersion:
Add SemVersion.equals; Amend hashCode; Add docs.
This commit is contained in:
parent
0c98abbb31
commit
0007a97d66
@ -47,10 +47,10 @@ import kotlin.LazyThreadSafetyMode.PUBLICATION
|
|||||||
* ```
|
* ```
|
||||||
* 其中 identifier 和 metadata 都是可选的.
|
* 其中 identifier 和 metadata 都是可选的.
|
||||||
*
|
*
|
||||||
* 对于核心版本号, 此实现稍微比 semver 宽松一些, 允许 x.y 的存在.
|
* 对于核心版本号, 此实现稍微比语义化版本规范宽松一些, 允许 x.y 的存在.
|
||||||
*
|
*
|
||||||
* @see Requirement
|
* @see Requirement 版本号要修
|
||||||
* @see SemVersion.invoke
|
* @see SemVersion.invoke 由字符串解析
|
||||||
*/
|
*/
|
||||||
@Serializable(with = SemVersion.SemVersionAsStringSerializer::class)
|
@Serializable(with = SemVersion.SemVersionAsStringSerializer::class)
|
||||||
public data class SemVersion
|
public data class SemVersion
|
||||||
@ -69,6 +69,15 @@ internal constructor(
|
|||||||
/** 版本号元数据, 不参与版本号对比([compareTo]), 但是参与版本号严格对比([equals]) */
|
/** 版本号元数据, 不参与版本号对比([compareTo]), 但是参与版本号严格对比([equals]) */
|
||||||
public val metadata: String? = null,
|
public val metadata: String? = null,
|
||||||
) : Comparable<SemVersion> {
|
) : Comparable<SemVersion> {
|
||||||
|
|
||||||
|
init {
|
||||||
|
require(major >= 0) { "major must >= 0" }
|
||||||
|
require(minor >= 0) { "minor must >= 0" }
|
||||||
|
if (patch != null) require(patch >= 0) { "patch must >= 0" }
|
||||||
|
if (identifier != null) require(identifier.none(Char::isWhitespace)) { "identifier must not contain whitespace" }
|
||||||
|
if (metadata != null) require(metadata.none(Char::isWhitespace)) { "metadata must not contain whitespace" }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 一条依赖规则
|
* 一条依赖规则
|
||||||
* @see [parseRangeRequirement]
|
* @see [parseRangeRequirement]
|
||||||
@ -103,9 +112,9 @@ internal constructor(
|
|||||||
* - 如果不确定版本号是否合法, 可以使用 [regex101.com](https://regex101.com/r/vkijKf/1/) 进行检查
|
* - 如果不确定版本号是否合法, 可以使用 [regex101.com](https://regex101.com/r/vkijKf/1/) 进行检查
|
||||||
* - 此实现使用的正则表达式为 `^(0|[1-9]\d*)\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`
|
* - 此实现使用的正则表达式为 `^(0|[1-9]\d*)\.(0|[1-9]\d*)(?:\.(0|[1-9]\d*))?(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`
|
||||||
*/
|
*/
|
||||||
@Throws(IllegalArgumentException::class, NumberFormatException::class)
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmName("parse")
|
@JvmName("parse")
|
||||||
|
@Throws(IllegalArgumentException::class, NumberFormatException::class)
|
||||||
public operator fun invoke(@ResolveContext(PLUGIN_VERSION) version: String): SemVersion = SemVersionInternal.parse(version)
|
public operator fun invoke(@ResolveContext(PLUGIN_VERSION) version: String): SemVersion = SemVersionInternal.parse(version)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -138,13 +147,14 @@ internal constructor(
|
|||||||
* - 如果目标版本号携带有先行版本号, 请不要忘记先行版本号
|
* - 如果目标版本号携带有先行版本号, 请不要忘记先行版本号
|
||||||
* - 因为 `()` 已经用于数学区间, 使用 `{}` 替代 `()`
|
* - 因为 `()` 已经用于数学区间, 使用 `{}` 替代 `()`
|
||||||
*/
|
*/
|
||||||
@Throws(IllegalArgumentException::class)
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@Throws(IllegalArgumentException::class)
|
||||||
public fun parseRangeRequirement(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Requirement =
|
public fun parseRangeRequirement(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Requirement =
|
||||||
SemVersionInternal.parseRangeRequirement(requirement)
|
SemVersionInternal.parseRangeRequirement(requirement)
|
||||||
|
|
||||||
/** @see [Requirement.test] */
|
/** @see [Requirement.test] */
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@Throws(IllegalArgumentException::class, NumberFormatException::class)
|
||||||
public fun Requirement.test(@ResolveContext(PLUGIN_VERSION) version: String): Boolean = test(invoke(version))
|
public fun Requirement.test(@ResolveContext(PLUGIN_VERSION) version: String): Boolean = test(invoke(version))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -157,6 +167,7 @@ internal constructor(
|
|||||||
* 当满足 [requirement] 时返回 true, 否则返回 false
|
* 当满足 [requirement] 时返回 true, 否则返回 false
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@Throws(IllegalArgumentException::class)
|
||||||
public fun SemVersion.satisfies(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Boolean = parseRangeRequirement(requirement).test(this)
|
public fun SemVersion.satisfies(@ResolveContext(VERSION_REQUIREMENT) requirement: String): Boolean = parseRangeRequirement(requirement).test(this)
|
||||||
|
|
||||||
/** for Kotlin only */
|
/** for Kotlin only */
|
||||||
@ -185,7 +196,10 @@ internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = toString
|
/**
|
||||||
|
* 返回类似 `1.0.0-M4+c25733b8` 的字符串.
|
||||||
|
*/
|
||||||
|
public override fun toString(): String = toString
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将 [SemVersion] 转为 Kotlin data class 风格的 [String]
|
* 将 [SemVersion] 转为 Kotlin data class 风格的 [String]
|
||||||
@ -194,27 +208,60 @@ internal constructor(
|
|||||||
return "SemVersion(major=$major, minor=$minor, patch=$patch, identifier=$identifier, metadata=$metadata)"
|
return "SemVersion(major=$major, minor=$minor, patch=$patch, identifier=$identifier, metadata=$metadata)"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
/**
|
||||||
if (this === other) return true
|
* 比较 `this` 和 [other].
|
||||||
if (javaClass != other?.javaClass) return false
|
*
|
||||||
|
* @param deep 为 `true` 时进行深度比较, 相当于 [equals]. 为 `false` 时相当于 `compareTo(other) == 0`
|
||||||
other as SemVersion
|
* @see compareTo
|
||||||
|
*/
|
||||||
return compareTo(other) == 0 && other.identifier == identifier && other.metadata == metadata
|
public fun equals(other: SemVersion, deep: Boolean): Boolean {
|
||||||
|
return if (deep) {
|
||||||
|
(other.major == major
|
||||||
|
&& other.minor == minor
|
||||||
|
&& other.patch == patch
|
||||||
|
&& other.identifier == identifier
|
||||||
|
&& other.metadata == metadata)
|
||||||
|
} else {
|
||||||
|
this.compareTo(other) == 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
/**
|
||||||
var result = major shl minor
|
* 深度比较 `this` 和 [other], 当且仅当 [major], [patch], [minor], [identifier], [metadata] 完全相同时返回 `true`.
|
||||||
result *= (patch ?: 1)
|
*
|
||||||
|
* 如: `1.0.0-RC` != `1.0-RC`
|
||||||
|
*
|
||||||
|
* @see compareTo
|
||||||
|
*/
|
||||||
|
public override fun equals(other: Any?): Boolean {
|
||||||
|
if (other === null) return false
|
||||||
|
if (this === other) return true
|
||||||
|
if (javaClass != other.javaClass) return false
|
||||||
|
return equals(other as SemVersion, deep = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun hashCode(): Int {
|
||||||
|
var result = major.hashCode()
|
||||||
|
result = 31 * result + minor.hashCode()
|
||||||
|
result = 31 * result + (patch?.hashCode() ?: 0)
|
||||||
result = 31 * result + (identifier?.hashCode() ?: 0)
|
result = 31 * result + (identifier?.hashCode() ?: 0)
|
||||||
result = 31 * result + (metadata?.hashCode() ?: 0)
|
result = 31 * result + (metadata?.hashCode() ?: 0)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares this object with the specified object for order. Returns zero if this object is equal
|
* 比较 `this` 和 [other] 的实际版本大小.
|
||||||
* to the specified [other] object, a negative number if it's less than [other], or a positive number
|
*
|
||||||
* if it's greater than [other].
|
* 如:
|
||||||
|
* - `SemVersion("1.0.0-RC").compareTo(SemVersion("1.0-RC")) == 0` (然而对他们进行 [equals] 判断会返回 `false`)
|
||||||
|
* - `SemVersion("1.3.0") > SemVersion("1.1.0") == true` (因为 1.3.0 比 1.1.0 更高)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @return 当 `this` 比 [other] 更高时返回一个正数.
|
||||||
|
* 当 `this` 比 [other] 更低时返回一个负数.
|
||||||
|
* 当 `this` 与 [other] 版本大小相等时返回 0.
|
||||||
|
*
|
||||||
|
* @see equals
|
||||||
*/
|
*/
|
||||||
public override operator fun compareTo(other: SemVersion): Int {
|
public override operator fun compareTo(other: SemVersion): Int {
|
||||||
return SemVersionInternal.run { compareInternal(this@SemVersion, other) }
|
return SemVersionInternal.run { compareInternal(this@SemVersion, other) }
|
||||||
|
Loading…
Reference in New Issue
Block a user