Skip to content

Config API enhancements needed for safe recursive config traversal #5

Description

@amorphobia

概述

SchemaOpen / ConfigOpen 丢弃了 native bool 返回值,而 GetList / GetMap 将三种不同状态(路径不存在、类型不匹配、空容器)坍缩为相同的结果。这些缺口使得下游调用方(如 RimeSharp.PowerShell 或其他绑定使用者)无法安全实现 Get-RimeConfigSnapshot——即递归复制配置树到托管内存、并能可靠区分错误状态与合法空数据的 cmdlet。

当前行为

// Rime.cs — SchemaOpen 忽略 native 返回值
public RimeConfig SchemaOpen(string schemaId)
{
    var config = new RimeConfig();
    _api.SchemaOpen(schemaId, ref config);   // bool 被丢弃
    return config;                            // 调用者无法得知是否有效
}
// RimeConfig.cs — GetList 将未找到、类型错误、空容器坍缩为同一结果
public T[] GetList<T>(string key, Func<RimeConfig, string, T?> getFunc)
{
    ...
    if (!api.ConfigBeginList(ref iter, ref this, key))
        return [];    // 三种不同情形 → 相同的空数组
    ...
}

GetMap 同理。

建议改动

1. 让 config 打开函数可失败

使用可空返回值

public RimeConfig? SchemaOpen(string schemaId)
{
    var config = new RimeConfig();
    return _api.SchemaOpen(schemaId, ref config) ? config : null;
}

ConfigOpenUserConfigOpen 同理。

2. 让节点类型可检测

暴露 ConfigBeginList / ConfigBeginMap 的返回值,让调用方能无歧义地探明某路径的节点类型。

方式一——在 RimeConfig 上新增方法:

public bool IsList(string key) => Rime.Instance().ConfigBeginList(key, ref this);
public bool IsMap(string key) => Rime.Instance().ConfigBeginMap(key, ref this);

方式二——单一查询方法:

public enum RimeConfigNodeType { NotFound, Scalar, List, Map }
public RimeConfigNodeType GetNodeType(string key);

影响范围

  • RimeSharp.PowerShell 可以安全地实现 Get-RimeConfigSnapshot
  • 当前 SchemaOpen/ConfigOpen 的现有调用方拿到一个有效性不可知RimeConfig——这是任何调用这些方法并使用结果的代码路径中的潜在 bug
  • 向后兼容:现有调用方可通过简单机械迁移更新(SchemaOpen(id)SchemaOpen(id, out var config)SchemaOpen(id) ?? fallback

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions