diff --git a/build.gradle.kts b/build.gradle.kts index 82dce1a..b5191f2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,3 @@ -import net.minecrell.pluginyml.paper.PaperPluginDescription - group = "net.hareworks" version = "1.1" @@ -33,7 +31,8 @@ paper { description = "Permission Library" version = getVersion().toString() apiVersion = "1.21.10" - authors = listOf( - "Hare-K02" - ) + authors = + listOf( + "Hare-K02", + ) } diff --git a/src/main/kotlin/net/hareworks/permits_lib/Plugin.kt b/src/main/kotlin/net/hareworks/permits_lib/Plugin.kt index 413bca3..25aa908 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/Plugin.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/Plugin.kt @@ -3,4 +3,4 @@ package net.hareworks.permits_lib.plugin import org.bukkit.plugin.java.JavaPlugin @Suppress("unused") -class Plugin : JavaPlugin() {} +class Plugin : JavaPlugin() diff --git a/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentPatch.kt b/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentPatch.kt index 9f9048a..3ba929c 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentPatch.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentPatch.kt @@ -7,7 +7,7 @@ import net.hareworks.permits_lib.domain.PermissionId * `true`/`false` represent forced grant/deny, while `null` removes the override. */ data class AttachmentPatch( - val changes: Map + val changes: Map, ) { companion object { val EMPTY = AttachmentPatch(emptyMap()) diff --git a/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentSynchronizer.kt b/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentSynchronizer.kt index 16954ef..d96c0b9 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentSynchronizer.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/bukkit/AttachmentSynchronizer.kt @@ -1,27 +1,30 @@ package net.hareworks.permits_lib.bukkit -import java.util.IdentityHashMap import net.hareworks.permits_lib.domain.PermissionId import net.hareworks.permits_lib.util.ThreadChecks -import org.bukkit.permissions.PermissionAttachment import org.bukkit.permissions.Permissible +import org.bukkit.permissions.PermissionAttachment import org.bukkit.plugin.java.JavaPlugin +import java.util.IdentityHashMap /** * Manages [PermissionAttachment] instances per [Permissible], applying patches and cleaning up once no * overrides remain. */ class AttachmentSynchronizer( - private val plugin: JavaPlugin + private val plugin: JavaPlugin, ) { private data class AttachmentHandle( val attachment: PermissionAttachment, - val overrides: MutableMap = linkedMapOf() + val overrides: MutableMap = linkedMapOf(), ) private val handles = IdentityHashMap() - fun applyPatch(permissible: Permissible, patch: AttachmentPatch) { + fun applyPatch( + permissible: Permissible, + patch: AttachmentPatch, + ) { ThreadChecks.ensurePrimaryThread("AttachmentSynchronizer.applyPatch") if (patch.changes.isEmpty()) return val handle = ensureHandle(permissible) @@ -39,11 +42,18 @@ class AttachmentSynchronizer( } } - fun grant(permissible: Permissible, permission: PermissionId, value: Boolean = true) { + fun grant( + permissible: Permissible, + permission: PermissionId, + value: Boolean = true, + ) { applyPatch(permissible, AttachmentPatch(mapOf(permission to value))) } - fun revoke(permissible: Permissible, permission: PermissionId) { + fun revoke( + permissible: Permissible, + permission: PermissionId, + ) { applyPatch(permissible, AttachmentPatch(mapOf(permission to null))) } diff --git a/src/main/kotlin/net/hareworks/permits_lib/bukkit/MutationSession.kt b/src/main/kotlin/net/hareworks/permits_lib/bukkit/MutationSession.kt index ffb21ef..e3171aa 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/bukkit/MutationSession.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/bukkit/MutationSession.kt @@ -9,7 +9,7 @@ import net.hareworks.permits_lib.domain.TreeDiff */ class MutationSession( private val registry: PermissionRegistry, - val attachments: AttachmentSynchronizer + val attachments: AttachmentSynchronizer, ) { private var tree: PermissionTree? = null private var diff: TreeDiff? = null @@ -34,19 +34,23 @@ class MutationSession( * Mutates the existing tree or creates a fresh one for the provided [namespace] when none was applied * before. */ - fun edit(namespace: String, block: MutablePermissionTree.() -> Unit): TreeDiff { - val mutable = tree?.let { - require(it.namespace == namespace) { - "Existing tree namespace '${it.namespace}' differs from requested '$namespace'." - } - MutablePermissionTree.from(it) - } ?: MutablePermissionTree.create(namespace) + fun edit( + namespace: String, + block: MutablePermissionTree.() -> Unit, + ): TreeDiff { + val mutable = + tree?.let { + require(it.namespace == namespace) { + "Existing tree namespace '${it.namespace}' differs from requested '$namespace'." + } + MutablePermissionTree.from(it) + } ?: MutablePermissionTree.create(namespace) return editInternal(mutable, block) } private fun editInternal( mutable: MutablePermissionTree, - block: MutablePermissionTree.() -> Unit + block: MutablePermissionTree.() -> Unit, ): TreeDiff { mutable.block() val next = mutable.build() @@ -61,13 +65,14 @@ class MutationSession( } fun currentTree(): PermissionTree? = tree + fun lastDiff(): TreeDiff? = diff companion object { fun create(plugin: org.bukkit.plugin.java.JavaPlugin): MutationSession = MutationSession( registry = PermissionRegistry(plugin), - attachments = AttachmentSynchronizer(plugin) + attachments = AttachmentSynchronizer(plugin), ) } } diff --git a/src/main/kotlin/net/hareworks/permits_lib/bukkit/PermissionRegistry.kt b/src/main/kotlin/net/hareworks/permits_lib/bukkit/PermissionRegistry.kt index b6da936..74b6e48 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/bukkit/PermissionRegistry.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/bukkit/PermissionRegistry.kt @@ -16,7 +16,7 @@ import org.bukkit.plugin.java.JavaPlugin */ class PermissionRegistry( private val plugin: JavaPlugin, - private val pluginManager: PluginManager = plugin.server.pluginManager + private val pluginManager: PluginManager = plugin.server.pluginManager, ) { private var snapshot: TreeSnapshot? = null diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/MutablePermissionTree.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/MutablePermissionTree.kt index 4405ddd..3544538 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/MutablePermissionTree.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/MutablePermissionTree.kt @@ -8,9 +8,13 @@ import org.bukkit.permissions.PermissionDefault */ class MutablePermissionTree internal constructor( private val namespace: String, - private val drafts: MutableMap + private val drafts: MutableMap, ) { - fun node(id: String, registration: NodeRegistration, block: MutableNode.() -> Unit = {}): MutableNode { + fun node( + id: String, + registration: NodeRegistration, + block: MutableNode.() -> Unit = {}, + ): MutableNode { require(id.isNotBlank()) { "Node id must not be blank." } val permissionId = PermissionId.of("$namespace.${id.lowercase()}") val draft = drafts.getOrPut(permissionId) { PermissionNodeDraft(permissionId) } @@ -24,7 +28,10 @@ class MutablePermissionTree internal constructor( removeSubtree(permissionId) } - fun renameNode(oldId: String, newId: String) { + fun renameNode( + oldId: String, + newId: String, + ) { require(oldId.isNotBlank()) { "Old node id must not be blank." } require(newId.isNotBlank()) { "New node id must not be blank." } val oldPermissionId = PermissionId.of("$namespace.${oldId.lowercase()}") @@ -44,7 +51,7 @@ class MutablePermissionTree internal constructor( inner class MutableNode internal constructor( val id: PermissionId, - private val draft: PermissionNodeDraft + private val draft: PermissionNodeDraft, ) { var description: String? get() = draft.description @@ -70,18 +77,28 @@ class MutablePermissionTree internal constructor( draft.registration = value } - fun child(id: String, value: Boolean = true) { + fun child( + id: String, + value: Boolean = true, + ) { require(id.isNotBlank()) { "Child id must not be blank." } val permissionId = PermissionId.of("${this.id.value}.${id.lowercase()}") draft.children[permissionId] = value } - fun childAbsolute(id: String, value: Boolean = true) { + fun childAbsolute( + id: String, + value: Boolean = true, + ) { val permissionId = PermissionId.of(id.lowercase()) draft.children[permissionId] = value } - fun node(id: String, registration: NodeRegistration, block: MutableNode.() -> Unit = {}) { + fun node( + id: String, + registration: NodeRegistration, + block: MutableNode.() -> Unit = {}, + ) { require(id.isNotBlank()) { "Node id must not be blank." } val permissionId = PermissionId.of("${this.id.value}.${id.lowercase()}") draft.children[permissionId] = true @@ -96,7 +113,10 @@ class MutablePermissionTree internal constructor( removeSubtree(permissionId) } - fun renameNode(oldId: String, newId: String) { + fun renameNode( + oldId: String, + newId: String, + ) { require(oldId.isNotBlank()) { "Old node id must not be blank." } require(newId.isNotBlank()) { "New node id must not be blank." } val oldPermissionId = PermissionId.of("${this.id.value}.${oldId.lowercase()}") @@ -119,9 +139,10 @@ class MutablePermissionTree internal constructor( private fun removeSubtree(rootId: PermissionId) { val prefix = "${rootId.value}." - val targets = drafts.keys.filter { key -> - key.value == rootId.value || key.value.startsWith(prefix) - }.toSet() + val targets = + drafts.keys.filter { key -> + key.value == rootId.value || key.value.startsWith(prefix) + }.toSet() if (targets.isEmpty()) return targets.forEach { drafts.remove(it) } drafts.values.forEach { draft -> @@ -135,12 +156,16 @@ class MutablePermissionTree internal constructor( } } - private fun renameSubtree(oldRoot: PermissionId, newRoot: PermissionId) { + private fun renameSubtree( + oldRoot: PermissionId, + newRoot: PermissionId, + ) { if (oldRoot == newRoot) return val prefix = "${oldRoot.value}." - val affected = drafts.keys.filter { key -> - key.value == oldRoot.value || key.value.startsWith(prefix) - } + val affected = + drafts.keys.filter { key -> + key.value == oldRoot.value || key.value.startsWith(prefix) + } if (affected.isEmpty()) return val affectedSet = affected.toSet() val mapping = linkedMapOf() @@ -156,15 +181,16 @@ class MutablePermissionTree internal constructor( mapping.forEach { (oldId, newId) -> val draft = drafts.remove(oldId) ?: return@forEach - val newDraft = PermissionNodeDraft( - id = newId, - description = draft.description, - defaultValue = draft.defaultValue, - children = draft.children.toMutableMap(), - wildcard = draft.wildcard, - registration = draft.registration, - wildcardExclusions = draft.wildcardExclusions.toMutableSet() - ) + val newDraft = + PermissionNodeDraft( + id = newId, + description = draft.description, + defaultValue = draft.defaultValue, + children = draft.children.toMutableMap(), + wildcard = draft.wildcard, + registration = draft.registration, + wildcardExclusions = draft.wildcardExclusions.toMutableSet(), + ) drafts[newId] = newDraft } @@ -184,13 +210,12 @@ class MutablePermissionTree internal constructor( } companion object { - fun create(namespace: String): MutablePermissionTree = - MutablePermissionTree(namespace.trim().lowercase(), linkedMapOf()) + fun create(namespace: String): MutablePermissionTree = MutablePermissionTree(namespace.trim().lowercase(), linkedMapOf()) fun from(tree: PermissionTree): MutablePermissionTree = MutablePermissionTree( namespace = tree.namespace, - drafts = tree.nodes.mapValues { PermissionNodeDraft.from(it.value) }.toMutableMap() + drafts = tree.nodes.mapValues { PermissionNodeDraft.from(it.value) }.toMutableMap(), ) } } diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/NodeRegistration.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/NodeRegistration.kt index 20c6f8d..c0b60a2 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/NodeRegistration.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/NodeRegistration.kt @@ -6,5 +6,5 @@ package net.hareworks.permits_lib.domain */ enum class NodeRegistration(val registersPermission: Boolean) { PERMISSION(true), - STRUCTURAL(false) + STRUCTURAL(false), } diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNode.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNode.kt index f20df75..a649f56 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNode.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNode.kt @@ -15,7 +15,7 @@ data class PermissionNode( val children: Map = emptyMap(), val wildcard: Boolean = false, val registration: NodeRegistration = NodeRegistration.PERMISSION, - val wildcardExclusions: Set = emptySet() + val wildcardExclusions: Set = emptySet(), ) { init { require(children.keys.none { it == id }) { "Permission node cannot be a child of itself." } diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNodeDraft.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNodeDraft.kt index f098558..6e66138 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNodeDraft.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionNodeDraft.kt @@ -9,7 +9,7 @@ internal data class PermissionNodeDraft( val children: MutableMap = linkedMapOf(), var wildcard: Boolean = false, var registration: NodeRegistration = NodeRegistration.PERMISSION, - val wildcardExclusions: MutableSet = linkedSetOf() + val wildcardExclusions: MutableSet = linkedSetOf(), ) { fun toNode(): PermissionNode = PermissionNode( @@ -19,7 +19,7 @@ internal data class PermissionNodeDraft( children = children.toMap(), wildcard = wildcard, registration = registration, - wildcardExclusions = wildcardExclusions.toSet() + wildcardExclusions = wildcardExclusions.toSet(), ) companion object { @@ -31,7 +31,7 @@ internal data class PermissionNodeDraft( children = node.children.toMutableMap(), wildcard = node.wildcard, registration = node.registration, - wildcardExclusions = node.wildcardExclusions.toMutableSet() + wildcardExclusions = node.wildcardExclusions.toMutableSet(), ) } } diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionTree.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionTree.kt index 2759876..f7f64eb 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionTree.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/PermissionTree.kt @@ -5,7 +5,7 @@ package net.hareworks.permits_lib.domain */ class PermissionTree internal constructor( val namespace: String, - internal val nodes: Map + internal val nodes: Map, ) { init { require(namespace.isNotBlank()) { "Permission namespace must not be blank." } @@ -15,13 +15,15 @@ class PermissionTree internal constructor( operator fun get(id: PermissionId): PermissionNode? = nodes[id] - fun toSnapshot(): TreeSnapshot = - TreeSnapshot(nodes.filterValues { it.registration.registersPermission }) + fun toSnapshot(): TreeSnapshot = TreeSnapshot(nodes.filterValues { it.registration.registersPermission }) companion object { fun empty(namespace: String): PermissionTree = PermissionTree(namespace, emptyMap()) - fun from(namespace: String, rawNodes: Map): PermissionTree { + fun from( + namespace: String, + rawNodes: Map, + ): PermissionTree { val augmented = WildcardAugmentor.apply(rawNodes) PermissionTreeValidator.validate(augmented) return PermissionTree(namespace, augmented) diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiff.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiff.kt index 8a49b28..e0a49b4 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiff.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiff.kt @@ -3,7 +3,7 @@ package net.hareworks.permits_lib.domain data class TreeDiff( val added: List, val removed: List, - val updated: List + val updated: List, ) { val hasChanges: Boolean get() = added.isNotEmpty() || removed.isNotEmpty() || updated.isNotEmpty() diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiffer.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiffer.kt index 4eb7259..6382b94 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiffer.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/TreeDiffer.kt @@ -1,7 +1,10 @@ package net.hareworks.permits_lib.domain object TreeDiffer { - fun diff(previous: TreeSnapshot?, next: TreeSnapshot): TreeDiff { + fun diff( + previous: TreeSnapshot?, + next: TreeSnapshot, + ): TreeDiff { val prevNodes = previous?.nodes.orEmpty() val nextNodes = next.nodes @@ -23,7 +26,7 @@ object TreeDiffer { return TreeDiff( added = added.sortedBy { it.id.value }, removed = removed.sortedBy { it.id.value }, - updated = updated.sortedBy { it.after.id.value } + updated = updated.sortedBy { it.after.id.value }, ) } } diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/TreeSnapshot.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/TreeSnapshot.kt index 0171cfd..2b17a7d 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/TreeSnapshot.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/TreeSnapshot.kt @@ -6,7 +6,7 @@ import java.security.MessageDigest * Snapshot of a tree at a specific point in time. Holds a deterministic digest useful for caching. */ class TreeSnapshot internal constructor( - internal val nodes: Map + internal val nodes: Map, ) { val digest: String = computeDigest(nodes) diff --git a/src/main/kotlin/net/hareworks/permits_lib/domain/WildcardAugmentor.kt b/src/main/kotlin/net/hareworks/permits_lib/domain/WildcardAugmentor.kt index 71cfa42..49d31ec 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/domain/WildcardAugmentor.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/domain/WildcardAugmentor.kt @@ -1,7 +1,5 @@ package net.hareworks.permits_lib.domain -import org.bukkit.permissions.PermissionDefault - internal object WildcardAugmentor { fun apply(nodes: Map): Map { if (nodes.isEmpty()) return nodes @@ -12,19 +10,21 @@ internal object WildcardAugmentor { if (node.id.value.endsWith(".*")) return@forEach val wildcardId = PermissionId.of("${node.id.value}.*") - val updatedChildren = node.children - .filterKeys { childId -> childId !in node.wildcardExclusions } - .toMutableMap() + val updatedChildren = + node.children + .filterKeys { childId -> childId !in node.wildcardExclusions } + .toMutableMap() val existing = result[wildcardId] if (existing == null) { - result[wildcardId] = PermissionNode( - id = wildcardId, - description = "Wildcard for ${node.id.value}", - defaultValue = node.defaultValue, - children = updatedChildren, - wildcard = false - ) + result[wildcardId] = + PermissionNode( + id = wildcardId, + description = "Wildcard for ${node.id.value}", + defaultValue = node.defaultValue, + children = updatedChildren, + wildcard = false, + ) } else { result[wildcardId] = existing.copy(children = updatedChildren) } diff --git a/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionNodeBuilder.kt b/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionNodeBuilder.kt index ecd2727..6aa71f3 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionNodeBuilder.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionNodeBuilder.kt @@ -8,7 +8,7 @@ import org.bukkit.permissions.PermissionDefault @PermissionDsl class PermissionNodeBuilder internal constructor( private val treeBuilder: PermissionTreeBuilder, - private val draft: PermissionNodeDraft + private val draft: PermissionNodeDraft, ) { var description: String? get() = draft.description @@ -39,18 +39,27 @@ class PermissionNodeBuilder internal constructor( draft.registration = value } - fun child(id: String, value: Boolean = true) { + fun child( + id: String, + value: Boolean = true, + ) { treeBuilder.childRelative(draft, id, value) } - fun child(id: PermissionId, value: Boolean = true) { + fun child( + id: PermissionId, + value: Boolean = true, + ) { treeBuilder.childAbsolute(draft, id.value, value) } /** * Links to a fully-qualified permission id. The provided [id] must already include its namespace. */ - fun childAbsolute(id: String, value: Boolean = true) { + fun childAbsolute( + id: String, + value: Boolean = true, + ) { treeBuilder.childAbsolute(draft, id, value) } @@ -66,20 +75,21 @@ class PermissionNodeBuilder internal constructor( fun node( id: String, registration: NodeRegistration, - block: PermissionNodeBuilder.() -> Unit = {} + block: PermissionNodeBuilder.() -> Unit = {}, ) { treeBuilder.nestedNode(draft, id, registration, block) } } class WildcardDsl internal constructor( - private val draft: PermissionNodeDraft + private val draft: PermissionNodeDraft, ) { fun exclude(vararg segments: String) { - val normalized = segments - .flatMap { it.split('.') } - .map { it.trim().lowercase() } - .filter { it.isNotEmpty() } + val normalized = + segments + .flatMap { it.split('.') } + .map { it.trim().lowercase() } + .filter { it.isNotEmpty() } if (normalized.isEmpty()) return val suffix = normalized.joinToString(".") val permissionId = PermissionId.of("${draft.id.value}.$suffix") diff --git a/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionTreeBuilder.kt b/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionTreeBuilder.kt index 1698c8c..5b51d28 100644 --- a/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionTreeBuilder.kt +++ b/src/main/kotlin/net/hareworks/permits_lib/dsl/PermissionTreeBuilder.kt @@ -7,14 +7,14 @@ import net.hareworks.permits_lib.domain.PermissionTree @PermissionDsl class PermissionTreeBuilder internal constructor( - private val namespace: String + private val namespace: String, ) { private val drafts = linkedMapOf() fun node( id: String, registration: NodeRegistration, - block: PermissionNodeBuilder.() -> Unit = {} + block: PermissionNodeBuilder.() -> Unit = {}, ) { require(id.isNotBlank()) { "Node id must not be blank." } val permissionId = PermissionId.of("$namespace.${id.lowercase()}") @@ -27,14 +27,15 @@ class PermissionTreeBuilder internal constructor( parent: PermissionNodeDraft, id: String, value: Boolean, - relative: Boolean + relative: Boolean, ) { - val target = if (relative) { - require(id.isNotBlank()) { "Child id must not be blank." } - "${parent.id.value}.${id.lowercase()}" - } else { - normalizeAbsolute(id) - } + val target = + if (relative) { + require(id.isNotBlank()) { "Child id must not be blank." } + "${parent.id.value}.${id.lowercase()}" + } else { + normalizeAbsolute(id) + } val permissionId = PermissionId.of(target) parent.children[permissionId] = value } @@ -42,20 +43,20 @@ class PermissionTreeBuilder internal constructor( internal fun childRelative( parent: PermissionNodeDraft, id: String, - value: Boolean + value: Boolean, ) = child(parent, id, value, relative = true) internal fun childAbsolute( parent: PermissionNodeDraft, id: String, - value: Boolean + value: Boolean, ) = child(parent, id, value, relative = false) internal fun nestedNode( parent: PermissionNodeDraft, id: String, registration: NodeRegistration, - block: PermissionNodeBuilder.() -> Unit + block: PermissionNodeBuilder.() -> Unit, ) { require(id.isNotBlank()) { "Nested node id must not be blank." } val composedId = PermissionId.of("${parent.id.value}.${id.lowercase()}") @@ -65,8 +66,7 @@ class PermissionTreeBuilder internal constructor( PermissionNodeBuilder(this, draft).apply(block) } - fun build(): PermissionTree = - PermissionTree.from(namespace, drafts.mapValues { it.value.toNode() }) + fun build(): PermissionTree = PermissionTree.from(namespace, drafts.mapValues { it.value.toNode() }) private fun normalizeAbsolute(id: String): String { require(id.isNotBlank()) { "Absolute permission id must not be blank." } @@ -74,5 +74,7 @@ class PermissionTreeBuilder internal constructor( } } -fun permissionTree(namespace: String, block: PermissionTreeBuilder.() -> Unit): PermissionTree = - PermissionTreeBuilder(namespace.trim().lowercase()).apply(block).build() +fun permissionTree( + namespace: String, + block: PermissionTreeBuilder.() -> Unit, +): PermissionTree = PermissionTreeBuilder(namespace.trim().lowercase()).apply(block).build()