知识包

KnowledgePack 与各条目类型、内嵌默认包、JSON 解析与序列化、覆盖包合并。

知识包是「语言无关标识 → 解读文本与门派属性」的 JSON。内核只判事实, 解读文本与星耀的门派属性放在这里。概念、格式与写覆盖包的方法见 知识包指南,完整字段表见仓库的 knowledge/SCHEMA.md

use x_iztro::{KnowledgePack, Language, StarKey};

let pack = KnowledgePack::builtin(Language::ZhCN).expect("zh-CN 有内嵌默认包");
let intro = pack.star_intro(StarKey::ZiweiMaj);

KnowledgePack 在 crate 根重导出;其余类型在 x_iztro::knowledge 下。

类型

KnowledgePack

字段全部公开,可直接读写;映射类字段是 BTreeMap,因此迭代顺序按键稳定。

字段类型说明
schemau32格式版本,当前为 SCHEMA_VERSION(1)
idString包标识,默认包为 "iztro-docs"
versionString包版本,默认包为「抓取日期+来源 commit 短号」
languageString文本语言的语言码,如 "zh-CN"
extendsOption<String>覆盖包所覆盖的包标识;独立包为 None
sourceSource来源与许可
starsBTreeMap<String, StarEntry>星耀条目,键为 StarKey::as_key
patternsBTreeMap<String, PatternEntry>格局条目,键为 PatternKey::as_key
palacesBTreeMap<String, TextEntry>宫位条目,键为 Palace::as_key
mutagensBTreeMap<String, TextEntry>四化条目,键为 Mutagen::as_key
conceptsBTreeMap<String, ConceptEntry>术语条目,键为 slug

实现 CloneDefaultPartialEqEqDebugSerializeDeserialize

Source

字段类型说明
nameOption<String>来源名称
urlOption<String>来源地址
commitOption<String>来源版本(git commit)
licenseOption<String>许可证
authorOption<String>作者
retrieved_atOption<String>取得日期
adaptedOption<String>改编说明:文本相对来源做了何种整理改写

StarEntry

字段类型说明
nameOption<String>该语言的显示名
categoryOption<String>类别:"major" / "minor" / "adjective" / "dec" / "flow"(流耀,指向对应本命辅星的对照性条目)
groupOption<String>分组:杂耀的分类、神煞的组别
attributesStarAttributes门派属性,缺省为全 None
introOption<String>解读正文(Markdown)
combinationsBTreeMap<String, String>与另一颗主星同宫的组合解读,键为对方星耀标识

StarAttributes

全部字段为 Option<String>aliasesOption<Vec<String>>yin_yangyin / yang)、five_elementswood / fire / earth / metal / water)、 stemjiagui)、five_elements_notedipperchemistrycareerdutyaliaseselement_colorenergy_color

这里的 five_elementsyin_yang 是知识包来源的说法,与核心 StarInfo 的取值可能不同——核心那份与 iztro 逐值一致。 原因见指南

PatternEntry

字段类型说明
nameOption<String>该语言的显示名
quotesOption<Vec<String>>古籍引文
conditionsOption<String>来源对成立条件的文字描述
introOption<String>解读正文

TextEntry / ConceptEntry

TextEntry(宫位、四化)有 nameintroConceptEntry(术语)有 titleintro, 都是 Option<String>

SCHEMA_VERSION

pub const SCHEMA_VERSION: u32 = 1;

本库支持的最高格式版本。解析到更高的 schema 会报错。


builtin

用途 取内嵌的默认知识包。

签名

impl KnowledgePack {
    pub fn builtin(language: Language) -> Option<&'static KnowledgePack>
}

参数

参数类型说明
languageLanguage文本语言

返回值 Option<&'static KnowledgePack>——该语言没有默认包时为 None。 目前只有 Language::ZhCN 有。首次调用时解析并缓存,之后是零成本的静态引用。

示例

let pack = KnowledgePack::builtin(Language::ZhCN).unwrap();
println!("{} {} {}", pack.id, pack.version, pack.stars.len());
println!("{:?}", pack.source.license);
println!("{}", KnowledgePack::builtin(Language::EnUS).is_some());

输出

iztro-docs 2026-08-19+ec2d58b 162
Some("MIT")
false

builtin_json

用途 取内嵌默认包的 JSON 原文,不做解析。

签名

impl KnowledgePack {
    pub fn builtin_json(language: Language) -> Option<&'static str>
}

返回值 Option<&'static str>,与 builtin 同样只有 zh-CN 有。 要把包原样透传给别的进程或写盘时用它,省一次解析加序列化。绑定层走的就是这条路。


from_json

用途 由 JSON 文本解析一份包。

签名

impl KnowledgePack {
    pub fn from_json(json: &str) -> Result<KnowledgePack, String>
}

返回值 Result<KnowledgePack, String>。错误是给人看的字符串,三种情况: JSON 语法或类型不合格式(invalid knowledge pack: ...)、 schema 缺失或为 0(包必须声明格式版本)、 以及 schema 高于 SCHEMA_VERSION(不做降级解析)。

这里返回 String 而不是 IztroError:知识包是调用方自带的数据, 不属于排盘入口的输入校验。绑定层会把它包成各语言的 invalid_argument 错误。

示例

let pack = KnowledgePack::from_json(r#"{
    "schema": 1, "id": "mine", "version": "1", "language": "zh-CN",
    "stars": {"ziweiMaj": {"intro": "我的紫微"}}
}"#)?;
println!("{:?}", pack.star_intro(StarKey::ZiweiMaj));
println!("{:?}", KnowledgePack::from_json(r#"{"schema": 99}"#));
println!("{:?}", KnowledgePack::from_json(r#"{"id": "x"}"#));

输出

Some("我的紫微")
Err("knowledge pack schema 99 is newer than supported 1")
Err("knowledge pack must declare \"schema\" (currently 1)")

边界与陷阱


to_json

用途 序列化为 JSON(紧凑,无缩进)。

签名

impl KnowledgePack {
    pub fn to_json(&self) -> String
}

返回值 String。为 None 的可选字段与空映射在输出里省略, 因此 from_json(&pack.to_json()) 与原包相等。要缩进输出用 serde_json::to_string_pretty(&pack)


merged

用途 把若干覆盖包依次叠加到本包上,返回新包。

签名

impl KnowledgePack {
    pub fn merged(&self, overlays: &[&KnowledgePack]) -> KnowledgePack
}

参数

参数类型说明
overlays&[&KnowledgePack]覆盖包,按数组顺序依次叠加,后面的覆盖前面的

返回值 KnowledgePack,本包与覆盖包都不变。 合并规则见指南: 逐段按键合并,覆盖包的非 None 字段覆盖同键条目的对应字段, attributescombinations 逐字段合并,数组字段整体替换。

示例

let base = KnowledgePack::builtin(Language::ZhCN).unwrap();
let overlay = KnowledgePack::from_json(r#"{
    "schema": 1, "id": "my-school", "version": "1", "language": "zh-CN", "extends": "iztro-docs",
    "stars": {"ziweiMaj": {"intro": "我的紫微", "attributes": {"aliases": ["帝座"]}}},
    "patterns": {"zi_fu_tong_gong": {"intro": "我的紫府同宫"}}
}"#)?;
let pack = base.merged(&[&overlay]);

let ziwei = pack.star(StarKey::ZiweiMaj).unwrap();
println!("{:?} {:?} {:?}", ziwei.name, ziwei.attributes.aliases, ziwei.attributes.chemistry);
println!("{:?}", pack.pattern_intro(PatternKey::ZiFuTongGong));
println!("{:?}", pack.pattern(PatternKey::ZiFuTongGong).unwrap().quotes);
println!("{} {:?}", pack.id, base.star_intro(StarKey::ZiweiMaj).map(|s| s.chars().take(5).collect::<String>()));

输出

Some("紫微") Some(["帝座"]) Some("尊贵")
Some("我的紫府同宫")
Some(["紫府同宫终身福厚。"])
my-school Some("紫微星号称")

merge

用途 把一份覆盖包就地合并进本包。

签名

impl KnowledgePack {
    pub fn merge(&mut self, overlay: &KnowledgePack)
}

merged 是它的不可变版本(克隆本包后逐个 merge)。 手里已经有一份可变的包、又要叠很多层时用 merge 省掉克隆。


star / pattern / palace / mutagen

用途 按语言无关标识取条目。

签名

impl KnowledgePack {
    pub fn star(&self, key: StarKey) -> Option<&StarEntry>
    pub fn pattern(&self, key: PatternKey) -> Option<&PatternEntry>
    pub fn palace(&self, palace: Palace) -> Option<&TextEntry>
    pub fn mutagen(&self, mutagen: Mutagen) -> Option<&TextEntry>
}

返回值 包里没有该条目时为 None。四个方法都是在对应 BTreeMap 上按 as_key() 取值,等价于自己写 pack.stars.get(key.as_key()); 术语没有专门的方法,直接 pack.concepts.get(slug)

示例

let pack = KnowledgePack::builtin(Language::ZhCN).unwrap();
let ziwei = pack.star(StarKey::ZiweiMaj).unwrap();

println!("{:?} {:?} {:?}", ziwei.name, ziwei.category, ziwei.attributes.dipper);
println!("{:?}", ziwei.combinations.keys().collect::<Vec<_>>());
println!("{:?}", pack.palace(Palace::Soul).and_then(|e| e.name.clone()));
println!("{:?}", pack.mutagen(Mutagen::Lu).and_then(|e| e.name.clone()));
println!("{:?}", pack.concepts.get("tong-gong").and_then(|e| e.title.clone()));

输出

Some("紫微") Some("major") Some("中天星系")
["pojunMaj", "qishaMaj", "tanlangMaj", "tianfuMaj", "tianxiangMaj"]
Some("命宫")
Some("化禄")
Some("遇、加、逢、同宫、同度")

star_intro / pattern_intro

用途 直接取解读正文,省掉一层 Option 展开。

签名

impl KnowledgePack {
    pub fn star_intro(&self, key: StarKey) -> Option<&str>
    pub fn pattern_intro(&self, key: PatternKey) -> Option<&str>
}

返回值 条目不存在、或条目存在但没写正文,都是 None

示例 把本命格局连同解读列出来:

let pack = KnowledgePack::builtin(Language::ZhCN).unwrap();
let chart = by_solar("2000-8-16", 2, Gender::Female, true, Language::ZhCN, Config::default())?;

for hit in chart.patterns() {
    let intro = pack.pattern_intro(hit.key).unwrap_or("(这份包里没写)");
    let head: String = intro.chars().take(10).collect();
    println!("{} {}", translate_pattern(hit.key, Language::ZhCN), head);
}

输出

府相朝垣 “食禄千锺”的断语使

本页目录