
love.forte.simbot.thing.Thing.kt Maven / Gradle / Ivy
/*
*
* * Copyright (c) 2021. ForteScarlet All rights reserved.
* * Project simple-robot
* * File MiraiAvatar.kt
* *
* * You can contact the author through the following channels:
* * github https://github.com/ForteScarlet
* * gitee https://gitee.com/ForteScarlet
* * email [email protected]
* * QQ 1149159218
*
*/
@file:JvmName("Somethings")
package love.forte.simbot.thing
/**
* 一个 **东西**。
* @author ForteScarlet
*/
interface Thing {
/**
* 被描述的对象。
*/
val value: T
}
/**
* 一个有结构的 [东西][Thing]. 除了自己,可能还会有很多.
*
* 结构应当是稳固的,因此 [children] 不应是可变动的。
*
*/
interface StructuralThing : Thing {
/**
* 被描述的对象。
*/
override val value: T
/**
* 结构化的东西中,会有很多小东西。
*/
val children: List>
}
/**
* 一个有 [名字][name] 的 [东西][Thing]。
*/
interface NamedThing : Thing {
/**
* 这个东西的名字。
*/
val name: String
/**
* 被描述的对象。
*/
override val value: T
}
/**
* 有名字的结构化事物。
*/
interface StructuralThingWithName : StructuralThing, NamedThing {
override val value: T
override val name: String
override val children: List>
}
/**
* 某种[东西][Thing]的构建器。
*/
public interface ThingBuilder> {
fun build(): B
}
////////
/**
* 根据层级name寻找指定结果。
*/
public fun StructuralThingWithName.resolveValue(vararg paths: String): T? = this.resolveValue(paths, 0)
private fun StructuralThingWithName.resolveValue(valuePath: Array, index: Int): T? {
if (valuePath.isEmpty()) return null
if (index > valuePath.lastIndex) return null
if (name != valuePath[index]) {
return null
}
if (index == valuePath.lastIndex && name == valuePath[index]) {
return value
}
for (child in this.children) {
val resolved = child.resolveValue(valuePath, index = (index + 1))
if (resolved != null) {
return resolved
}
}
return null
}
/**
* 将 [StructuralThingWithName] 解析为 [Map].
* 如果 [resolveRoot] 为 false,则不解析当前节点。
*/
@JvmOverloads
public fun StructuralThingWithName.resolveToMap(
delimiter: String,
resolveRoot: Boolean = true,
filter: (T) -> Boolean = { it != null },
): Map {
val map = mutableMapOf()
fun deep(parent: String? = null, t: StructuralThingWithName) {
val name = parent?.let { p -> p + delimiter + t.name } ?: t.name
if (filter(t.value)) {
map[name] = t.value
}
for (child in t.children) {
deep(name, child)
}
}
if (resolveRoot) {
if (filter(value)) {
map[name] = value
return map
}
for (child in children) {
deep(name, child)
}
} else {
if (children.isNotEmpty()) {
for (child in children) {
deep(null, child)
}
}
}
return map
}
/**
* 根据name过滤条件查找一个值。
*/
public fun StructuralThingWithName.findValue(filter: (name: String) -> Boolean): T? {
if (filter(name)) {
return value
}
if (children.isEmpty()) {
return null
}
children.forEach { c ->
val found = c.findValue(filter)
if (found != null) {
return found
}
}
return null
}
// Thing 基础实现
/**
* 对 [Thing] 的基础实现。
*/
public fun thing(value: T): Thing = SimpleThing(value)
public data class SimpleThing(override val value: T) : Thing
/**
* 得到一个没有内容的 [Thing].
*/
public fun nothing(): Thing = EmptyThing
private object EmptyThing : Thing {
override val value: Nothing? get() = null
override fun toString(): String = "EmptyThing(value=null)"
}
/**
* 对 [有名字的东西][NamedThing] 的基础实现。
*/
public fun thing(name: String, value: T): NamedThing = SimpleNamedThing(name, value)
public data class SimpleNamedThing(override val name: String, override val value: T) : NamedThing
/**
* 对 [结构化事物][StructuralThing] 的基础实现。
*/
public fun thing(value: T, children: List>): StructuralThing =
SimpleStructuralThing(value, children)
public fun emptyStructuralThing(value: T): StructuralThing = thing(value, emptyList())
public data class SimpleStructuralThing(
override val value: T,
override val children: List>,
) : StructuralThing
/**
* 对 [有名字的结构化事物][StructuralThingWithName] 的基础实现。
*/
public fun thing(name: String, value: T, children: List>): StructuralThingWithName =
SimpleStructuralThingWithName(name, value, children)
public fun emptyStructuralThing(name: String, value: T): StructuralThingWithName = thing(name, value, emptyList())
public data class SimpleStructuralThingWithName(
override val name: String, override val value: T,
override val children: List>,
) : StructuralThingWithName
public fun StructuralThing.forEach(block: StructuralThingForEach) {
block(null, this)
this.children.forEach {
it.forEach(this, block)
}
}
private fun StructuralThing.forEach(
parentThing: Thing,
block: StructuralThingForEach,
) {
block(parentThing, this)
this.children.forEach {
it.forEach(this, block)
}
}
@JvmName("forEachNamed")
public fun StructuralThingWithName.forEach(block: StructuralThingWithNameForEach) {
block(null, this)
this.children.forEach {
it.forEach(this, block)
}
}
@JvmName("forEachNamed")
private fun StructuralThingWithName.forEach(
parentThing: NamedThing,
block: StructuralThingWithNameForEach,
) {
block(parentThing, this)
this.children.forEach {
it.forEach(this, block)
}
}
public fun interface StructuralThingForEach {
operator fun invoke(parentThing: Thing?, thing: Thing)
}
public fun interface StructuralThingWithNameForEach {
operator fun invoke(parentThing: NamedThing?, thing: NamedThing)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy