mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-05 12:05:58 +01:00
Depth: change internal representation and API, implement Comparable<Int>
This commit is contained in:
parent
95f5f58843
commit
65ff597f58
4 changed files with 57 additions and 52 deletions
|
@ -7,16 +7,16 @@ package org.pgpainless.wot.network
|
|||
/**
|
||||
* Depth of a trust signature.
|
||||
*/
|
||||
class Depth private constructor(val limit: Int?) : Comparable<Depth> {
|
||||
class Depth private constructor(private val limit: Int) : Comparable<Int> {
|
||||
|
||||
// Uses a byte for internal representation, like in the OpenPGP "Trust Signature" subpacket
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The target is trusted to an unlimited degree.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun unconstrained() : Depth {
|
||||
return Depth(null)
|
||||
}
|
||||
fun unconstrained() = Depth(255)
|
||||
|
||||
/**
|
||||
* The target is trusted to a limited degree.
|
||||
|
@ -34,40 +34,35 @@ class Depth private constructor(val limit: Int?) : Comparable<Depth> {
|
|||
*/
|
||||
@JvmStatic
|
||||
fun auto(limit: Int): Depth {
|
||||
return if (limit == 255) {
|
||||
unconstrained()
|
||||
} else {
|
||||
limited(limit)
|
||||
require(limit in 0..255) {
|
||||
"Trust depth MUST be a value between 0 and 255."
|
||||
}
|
||||
return Depth(limit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if the [Depth] is unconstrained.
|
||||
*/
|
||||
fun isUnconstrained() : Boolean {
|
||||
return limit == null
|
||||
}
|
||||
fun isUnconstrained() = limit == 255
|
||||
|
||||
/**
|
||||
* The value of this Depth, as used in OpenPGP.
|
||||
*
|
||||
* Unlimited is 255.
|
||||
*/
|
||||
fun value(): Int {
|
||||
return limit ?: 255
|
||||
}
|
||||
fun value() = limit
|
||||
|
||||
/**
|
||||
* Decrease the trust depth by one and return the result.
|
||||
* Decrease the trust depth by `value` and return the result.
|
||||
* If the [Depth] is unconstrained, the result will still be unconstrained.
|
||||
* @throws IllegalArgumentException if the [Depth] cannot be decreased any further
|
||||
*/
|
||||
fun decrease(value : Int) : Depth {
|
||||
fun decrease(value: Int): Depth {
|
||||
return if (isUnconstrained()) {
|
||||
unconstrained()
|
||||
} else {
|
||||
if (limit!! >= value) {
|
||||
if (limit >= value) {
|
||||
limited(limit - value)
|
||||
} else {
|
||||
throw IllegalArgumentException("Depth cannot be decreased.")
|
||||
|
@ -78,20 +73,20 @@ class Depth private constructor(val limit: Int?) : Comparable<Depth> {
|
|||
/**
|
||||
* Return the minimum [Depth] of this and the other [Depth].
|
||||
*/
|
||||
fun min(other: Depth) : Depth {
|
||||
return if (compareTo(other) <= 0) {
|
||||
this
|
||||
} else {
|
||||
fun min(other: Depth): Depth {
|
||||
return if (limit > other.limit) {
|
||||
other
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
override fun compareTo(other: Depth): Int {
|
||||
return when (Pair(isUnconstrained(), other.isUnconstrained())) {
|
||||
Pair(true, true) -> 0
|
||||
Pair(true, false) -> 1
|
||||
Pair(false, true) -> -1
|
||||
else -> limit!!.compareTo(other.limit!!)
|
||||
override fun compareTo(other: Int): Int {
|
||||
return if (isUnconstrained()) {
|
||||
// If this is unconstrained, it is bigger than `other`
|
||||
1
|
||||
} else {
|
||||
limit.compareTo(other)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,11 +98,13 @@ class Depth private constructor(val limit: Int?) : Comparable<Depth> {
|
|||
return limit == other.limit
|
||||
}
|
||||
|
||||
override fun toString() : String {
|
||||
return if (isUnconstrained()) { "unconstrained" } else { limit!!.toString() }
|
||||
override fun toString(): String {
|
||||
return if (isUnconstrained()) {
|
||||
"unconstrained"
|
||||
} else {
|
||||
limit.toString()
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return limit ?: 0 // TODO: 255?
|
||||
}
|
||||
override fun hashCode() = limit
|
||||
}
|
|
@ -33,11 +33,11 @@ data class EdgeComponent(
|
|||
) {
|
||||
|
||||
override fun toString(): String {
|
||||
return if (trustDepth.limit == 0)
|
||||
"${issuer.fingerprint} certifies binding: $userId <-> ${target.fingerprint} [$trustAmount]"
|
||||
else {
|
||||
return if (trustDepth > 0) {
|
||||
val scope = if (regexes.regexStrings.isEmpty()) "" else ", scope: $regexes"
|
||||
"${issuer.fingerprint} delegates to ${target.fingerprint} [$trustAmount, depth $trustDepth$scope]"
|
||||
} else {
|
||||
"${issuer.fingerprint} certifies binding: $userId <-> ${target.fingerprint} [$trustAmount]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -97,7 +97,7 @@ class Path(
|
|||
require(target.fingerprint == nComponent.issuer.fingerprint) {
|
||||
"Cannot append edge to path: Path's tail is not issuer of the edge."
|
||||
}
|
||||
require(residualDepth.isUnconstrained() || residualDepth.limit!! > 0) {
|
||||
require(residualDepth > 0) {
|
||||
"Not enough depth."
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,10 @@ import org.junit.jupiter.api.assertThrows
|
|||
import org.pgpainless.wot.network.Depth.Companion.auto
|
||||
import org.pgpainless.wot.network.Depth.Companion.limited
|
||||
import org.pgpainless.wot.network.Depth.Companion.unconstrained
|
||||
import kotlin.test.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DepthTest {
|
||||
|
||||
|
@ -22,14 +25,15 @@ class DepthTest {
|
|||
@Test
|
||||
fun `verify Depth#unconstrained() has null depth`() {
|
||||
val depth = unconstrained()
|
||||
assertNull(depth.limit)
|
||||
assert(depth.isUnconstrained())
|
||||
assertEquals(depth.value(), 255)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify Depth#limited(2) initializes properly`() {
|
||||
val limited = limited(2)
|
||||
assertNotNull(limited.limit)
|
||||
assertEquals(2, limited.limit)
|
||||
assert(!limited.isUnconstrained())
|
||||
assertEquals(2, limited.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -50,7 +54,7 @@ class DepthTest {
|
|||
val limited = limited(3)
|
||||
val decreased = limited.decrease(2)
|
||||
assertFalse(decreased.isUnconstrained())
|
||||
assertEquals(1, decreased.limit)
|
||||
assertEquals(1, decreased.value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -63,17 +67,21 @@ class DepthTest {
|
|||
@Test
|
||||
fun `verify proper function of compareTo()`() {
|
||||
val unlimited = unconstrained()
|
||||
val unlimited2 = unconstrained()
|
||||
val depth2 = limited(2)
|
||||
val depth2_ = limited(2)
|
||||
val depth5 = limited(5)
|
||||
assertEquals(0, unlimited.compareTo(unlimited2))
|
||||
assertTrue(unlimited.compareTo(depth2) > 0)
|
||||
assertTrue(unlimited.compareTo(depth5) > 0)
|
||||
assertTrue(depth2.compareTo(unlimited) < 0)
|
||||
assertTrue(depth2.compareTo(depth5) < 0)
|
||||
assertTrue(depth5.compareTo(depth2) > 0)
|
||||
assertEquals(0, depth2.compareTo(depth2_))
|
||||
assertTrue(unlimited > 0)
|
||||
assertTrue(unlimited > 255)
|
||||
assertTrue(unlimited > 256)
|
||||
|
||||
assertTrue(depth2 > 0)
|
||||
assertTrue(depth2 > 1)
|
||||
assertFalse(depth2 > 2)
|
||||
assertFalse(depth2 > 256)
|
||||
|
||||
assertTrue(depth5 > 1)
|
||||
assertTrue(depth5 > 4)
|
||||
assertFalse(depth5 > 5)
|
||||
assertFalse(depth5 > 256)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -108,7 +116,7 @@ class DepthTest {
|
|||
@Test
|
||||
fun `verify that Depth#auto(255) yields an unconstrained Depth`() {
|
||||
assertTrue { auto(255).isUnconstrained() }
|
||||
assertNull(auto(255).limit)
|
||||
assertEquals(auto(255).value(), 255)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -117,7 +125,7 @@ class DepthTest {
|
|||
assertFalse { auto(120).isUnconstrained() }
|
||||
assertFalse { auto(254).isUnconstrained() }
|
||||
|
||||
assertNotNull(auto(42).limit)
|
||||
assertNotNull(auto(42).value())
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in a new issue