All Downloads are FREE. Search and download functionalities are using the official Maven repository.

love.forte.simbot.thing.Thing.kt Maven / Gradle / Ivy

There is a newer version: 3.0.0.preview.0.4
Show newest version
/*
 *
 *  * 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