///|
/// 管理端的设置(setting)、驱动(driver)与索引(index)模型。
///
/// 这里额外处理两件 Go 的事:JSON 键叫 `type` 的字段(MoonBit 保留字,
/// 统一命名 `item_type`),以及只有 64 位才能容纳的 `obj_count`
/// (core json 的 `UInt64` 只认字符串,所以对外用 `Int64`)。
///|
/// 一项系统设置(`/api/admin/setting/*` 的读写对象)。
pub(all) struct SettingItem {
/// 设置键。
key : String
/// 设置值(统一是字符串)。
value : String
/// 帮助文本。
help : String
/// 值类型,如 `string`、`bool`、`number`、`select`(对应 JSON 键 `type`)。
item_type : String
/// 可选值(`type = select` 时)。
options : String
/// 分组编号。
group : Int
/// 可见范围标记:0 公开、1 私有、2 只读、3 已废弃。
flag : Int
/// 组内排序。
index : UInt
}
///|
/// 解码设置项。
pub impl @json.FromJson for SettingItem with fn from_json(json, path) {
guard json is Object(fields) else {
raise @json.JsonDecodeError((path, "SettingItem: expected object"))
}
{
key: string_field(fields, "key"),
value: string_field(fields, "value"),
help: string_field(fields, "help"),
item_type: string_field(fields, "type"),
options: string_field(fields, "options"),
group: int_field(fields, "group"),
flag: int_field(fields, "flag"),
index: uint_field(fields, "index"),
}
}
///|
/// 显式声明手写的 `FromJson` 实现以普通方法暴露。
pub extend SettingItem with @json.FromJson::{from_json}
///|
/// 编码设置项(`save_settings` 要把设置原样回传,JSON 键是 `type`)。
pub impl ToJson for SettingItem with fn to_json(self) {
Json::object({
"key": Json::string(self.key),
"value": Json::string(self.value),
"help": Json::string(self.help),
"type": Json::string(self.item_type),
"options": Json::string(self.options),
"group": Json::number(self.group.to_double()),
"flag": Json::number(self.flag.to_double()),
"index": Json::number(self.index.to_double()),
})
}
///|
/// 显式声明手写的 `ToJson` 实现以普通方法暴露。
pub extend SettingItem with ToJson::{to_json}
///|
/// 驱动的一个配置项描述。
pub struct DriverItem {
/// 配置项名。
name : String
/// 输入类型,如 `string`、`bool`、`select`。
item_type : String
/// 默认值。
default : String
/// 可选值(`type = select` 时)。
options : String
/// 是否必填。
required : Bool
/// 帮助文本。
help : String
}
///|
/// 解码驱动配置项描述。
pub impl @json.FromJson for DriverItem with fn from_json(json, path) {
guard json is Object(fields) else {
raise @json.JsonDecodeError((path, "DriverItem: expected object"))
}
{
name: string_field(fields, "name"),
item_type: string_field(fields, "type"),
default: string_field(fields, "default"),
options: string_field(fields, "options"),
required: bool_field(fields, "required"),
help: string_field(fields, "help"),
}
}
///|
/// 显式声明手写的 `FromJson` 实现以普通方法暴露。
pub extend DriverItem with @json.FromJson::{from_json}
///|
/// 驱动能力声明。
pub struct DriverConfig {
/// 驱动名。
name : String
/// 是否支持本地排序。
local_sort : Bool
/// 是否只允许走代理下载。
only_proxy : Bool
/// 是否禁用缓存。
no_cache : Bool
/// 是否禁止上传。
no_upload : Bool
/// 是否需要用户提供额外信息(如验证码)。
need_ms : Bool
/// 默认根路径。
default_root : String
/// 提示信息。
alert : String
/// 是否只存索引(如 UrlTree 驱动)。
only_indices : Bool
/// 是否即使有直链也优先走代理。
prefer_proxy : Bool
}
///|
/// 解码驱动能力声明。
pub impl @json.FromJson for DriverConfig with fn from_json(json, path) {
guard json is Object(fields) else {
raise @json.JsonDecodeError((path, "DriverConfig: expected object"))
}
{
name: string_field(fields, "name"),
local_sort: bool_field(fields, "local_sort"),
only_proxy: bool_field(fields, "only_proxy"),
no_cache: bool_field(fields, "no_cache"),
no_upload: bool_field(fields, "no_upload"),
need_ms: bool_field(fields, "need_ms"),
default_root: string_field(fields, "default_root"),
alert: string_field(fields, "alert"),
only_indices: bool_field(fields, "only_indices"),
prefer_proxy: bool_field(fields, "prefer_proxy"),
}
}
///|
/// 显式声明手写的 `FromJson` 实现以普通方法暴露。
pub extend DriverConfig with @json.FromJson::{from_json}
///|
/// 一个驱动(或一个存储驱动实例)的完整描述。
pub struct DriverInfo {
/// 所有驱动共有的配置项。
common : Array[DriverItem]
/// 该驱动特有的配置项。
additional : Array[DriverItem]
/// 能力声明。
config : DriverConfig
}
///|
/// 解码驱动描述。
pub impl @json.FromJson for DriverInfo with fn from_json(json, path) {
guard json is Object(fields) else {
raise @json.JsonDecodeError((path, "DriverInfo: expected object"))
}
{
common: array_field(fields, "common"),
additional: array_field(fields, "additional"),
config: json_field(fields, "config").unwrap_or({
name: "",
local_sort: false,
only_proxy: false,
no_cache: false,
no_upload: false,
need_ms: false,
default_root: "",
alert: "",
only_indices: false,
prefer_proxy: false,
}),
}
}
///|
/// 显式声明手写的 `FromJson` 实现以普通方法暴露。
pub extend DriverInfo with @json.FromJson::{from_json}
///|
/// 索引构建进度(`GET /api/admin/index/progress`)。
pub struct IndexProgress {
/// 已索引的对象数。
obj_count : Int64
/// 是否已完成。
is_done : Bool
/// 上次完成时间(RFC3339 字符串);从未完成时是 `None`。
last_done_time : String?
/// 失败原因;没有错误时是空字符串。
error : String
}
///|
/// 解码索引进度。
pub impl @json.FromJson for IndexProgress with fn from_json(json, path) {
guard json is Object(fields) else {
raise @json.JsonDecodeError((path, "IndexProgress: expected object"))
}
{
obj_count: int64_field(fields, "obj_count"),
is_done: bool_field(fields, "is_done"),
last_done_time: json_field(fields, "last_done_time"),
error: string_field(fields, "error"),
}
}
///|
/// 显式声明手写的 `FromJson` 实现以普通方法暴露。
pub extend IndexProgress with @json.FromJson::{from_json}
///|
/// 系统初始化状态(`GET /api/public/init_status`)。
pub struct InitStatus {
/// 是否已经完成初始化(已完成则不能再调用 `init_setup`)。
initialized : Bool
}
///|
/// 解码初始化状态。
pub impl @json.FromJson for InitStatus with fn from_json(json, path) {
guard json is Object(fields) else {
raise @json.JsonDecodeError((path, "InitStatus: expected object"))
}
{ initialized: bool_field(fields, "initialized"), }
}
///|
/// 显式声明手写的 `FromJson` 实现以普通方法暴露。
pub extend InitStatus with @json.FromJson::{from_json}