kovi-plugin-ciyi 0.1.3

Kovi 的词意(猜词游戏)插件。
Documentation
use kovi::toml;
use kovi::utils::load_toml_data;
use serde::{Deserialize, Serialize};
use std::error::Error;
use std::path::PathBuf;
use std::sync::OnceLock;

use crate::p_command;

pub static COMMAND: OnceLock<p_command::CommandConfig> = OnceLock::new();
pub fn commands() -> &'static p_command::CommandConfig {
    COMMAND.get().expect("Commands not initialized")
}

pub const DEFAULT_COMMANDS_STR: &str = r#"
# 定义插件的指令。每个 [[command]] 块代表一种功能及其关联的触发词。
# function: 功能的内部描述,用于代码逻辑判断。
# commands: 用户可以输入的指令列表。

[[command]]
function = "查看插件指令列表"
commands = ["词意帮助", "词意指令", "词意指令列表", "词意帮助列表"]

[[command]]
function = "查看词意游戏规则"
commands = ["词意玩法", "词意规则"]

[[command]]
function = "猜测两字词语"
commands = ["词意猜测"]

[[command]]
function = "查看当前频道的词意排行榜"
commands = ["词意榜"]

[[command]]
function = "查看所有人的词意排行榜"
commands = ["词意全榜"]

[[command]]
function = "切换猜测模式"
commands = ["切换猜测模式"]
"#;

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CommandEntry {
    pub function: String,
    pub commands: Vec<String>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct CommandConfig {
    pub command: Vec<CommandEntry>,

    #[serde(skip)]
    config_file_path: PathBuf,
}

impl CommandConfig {
    pub fn new(data_dir: PathBuf) -> Result<Self, Box<dyn Error>> {
        if !data_dir.exists() {
            std::fs::create_dir_all(&data_dir)?;
        }

        let config_file_path = data_dir.join("command.toml");

        let default_config: CommandConfig = toml::from_str(DEFAULT_COMMANDS_STR)?;

        let mut config: CommandConfig = load_toml_data(default_config, config_file_path.clone())?;

        config.config_file_path = config_file_path;

        Ok(config)
    }

    pub fn get_function_by_command(&self, cmd_str: &str) -> Option<&String> {
        for entry in &self.command {
            if entry.commands.iter().any(|cmd| cmd == cmd_str) {
                return Some(&entry.function);
            }
        }
        None
    }
}