1use serde::Serialize;
8
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
16#[serde(rename_all = "snake_case")]
17pub enum Intent {
18 Natal,
20 Fortune,
22 Event,
24 Election,
26 Synastry,
28 Mundane,
30 Locative,
32 Onomancy,
34}
35
36impl Intent {
37 #[must_use]
39 pub fn id(self) -> &'static str {
40 match self {
41 Self::Natal => "natal",
42 Self::Fortune => "fortune",
43 Self::Event => "event",
44 Self::Election => "election",
45 Self::Synastry => "synastry",
46 Self::Mundane => "mundane",
47 Self::Locative => "locative",
48 Self::Onomancy => "onomancy",
49 }
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
55pub enum IntentStatus {
56 Live,
58 Pending,
60}
61
62impl IntentStatus {
63 #[must_use]
65 pub fn label(self) -> &'static str {
66 match self {
67 Self::Live => "已上线",
68 Self::Pending => "待承接",
69 }
70 }
71}
72
73#[derive(Debug, Clone, Copy, Serialize)]
78pub struct IntentSpec {
79 pub id: Intent,
81 pub name_zh: &'static str,
83 pub atoms: &'static [&'static str],
85 pub output_shape: &'static str,
87 pub status: IntentStatus,
89 pub note: &'static str,
91}
92
93const fn i(
95 id: Intent,
96 name_zh: &'static str,
97 atoms: &'static [&'static str],
98 output_shape: &'static str,
99 status: IntentStatus,
100 note: &'static str,
101) -> IntentSpec {
102 IntentSpec { id, name_zh, atoms, output_shape, status, note }
103}
104
105#[must_use]
110pub fn intents() -> &'static [IntentSpec] {
111 use IntentStatus::Live;
112 const { &[
113 i(
114 Intent::Natal, "命(本命盘)",
115 &["instant", "geo", "sex", "text(name)"],
116 "盘(静态切片,全树并行 fan-out)", Live,
117 "一个时刻的静态切片。全部时刻叶都答这一类,故它也是一片叶不作声明时的缺省",
118 ),
119 i(
120 Intent::Fortune, "运(运势/流年/大运)",
121 &["instant(birth)", "instant(target)", "sex"],
122 "势(时间序列,playhead 切片)", Live,
123 "本命固定、目标时刻在动:同一张底盘上取某一刻的切片,并沿时间轴铺成序列",
124 ),
125 i(
126 Intent::Event, "事(占事)",
127 &["instant(ask)", "seed(draw)", "text(question)"],
128 "断(成败/吉凶/宜忌)", Live,
129 "问事此刻加一次取机;取机的种子入盘,故同一次占问可复现",
130 ),
131 i(
132 Intent::Election, "择(择吉)",
133 &["window(start, end, grain)", "category(婚/葬/动土/行/开业…)"],
134 "期/序(候选日按吉凶排名)", Live,
135 "在一段时窗上逐日取要素并分档。事类宜忌各家出入大,不合成总分;\
136 各家分档的粒度与判据也不同,故这一类目前由单叶作答,合成总排名等于替读者选边",
137 ),
138 i(
139 Intent::Synastry, "合(合盘)",
140 &["instant(a)", "instant(b)", "sex(a,b)"],
141 "配(契合度/互补结构)", Live,
142 "两张本命之间的互供关系,两个方向分别成立,不对称是常态",
143 ),
144 i(
145 Intent::Mundane, "群/国(国运)",
146 &["instant(polity)", "geo"],
147 "势(国运势卜/年度盘)", Live,
148 "以政体奠基时刻为起点的周期结构,沿年份展开;描述的是周期位置,不是对现实的断言",
149 ),
150 i(
151 Intent::Locative, "寻(寻方位)",
152 &["instant(ask)", "seed(draw)", "category(寻人/物/向)"],
153 "位(方位/卦象)", Live,
154 "于问事此刻起课,从盘上抽方位候选(奇门取值符 / 值使 / 三吉门 / 三奇落宫 → 后天八卦方位,六壬取三传或四课上神 → 十二支方位);取用之法各家不同,不合成排名",
155 ),
156 i(
157 Intent::Onomancy, "号(字/词)",
158 &["text(name)", "strokes(姓笔画, 名笔画)"],
159 "号(数字学生命灵数/姓名值/五格)", Live,
160 "唯一不吃时刻的一类:入参是字与笔画,故走 WordEngine 而非 CastingEngine;\
161 数字学同时吃出生日期,因此它两边都在",
162 ),
163 ] }
164}