⎇ d3649bfd1a80153652c2a028315369bb4b184024
crates/modules/tahuantinsuyu/tahuantinsuyu-engine/src/dignity.rs
Historia
Quién tocó qué
crudo
feat(tahuantinsuyu): fase 18 — aspect list + hover tooltips + dignidades + export SVG
1//! Dignidades esenciales clásicas — tabla data-only.
2//!
3//! Cada planeta tradicional tiene cuatro estatus posibles según el
4//! signo en el que cae:
5//!
6//! - **Domicilio** (rulership) — el signo del que es regente.
7//! - **Exaltación** — un signo "huésped" que le da fuerza extra.
8//! - **Exilio** (detriment) — opuesto al domicilio, debilita.
9//! - **Caída** (fall) — opuesto a la exaltación, debilita.
10//!
11//! Esta tabla usa las regencias **clásicas** (Aries=Marte, Escorpio=
12//! Marte, Acuario=Saturno, Piscis=Júpiter) — los planetas modernos
13//! (Urano/Neptuno/Plutón) no tienen regencia clásica por convención.
14//! En una fase futura podemos exponer un toggle "regencias modernas"
15//! que mapee Escorpio→Plutón, Acuario→Urano, Piscis→Neptuno.
16
17use eternal_sky::Body;
18
19/// Status de dignidad esencial de un cuerpo en un signo dado.
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum Dignity {
22 /// Domicilio. Marker `"+"`.
23 Rulership,
24 /// Exaltación. Marker `"·"`.
25 Exaltation,
26 /// Exilio. Marker `"−"`.
27 Detriment,
28 /// Caída. Marker `"*"`.
29 Fall,
30}
31
32impl Dignity {
33 pub fn marker(self) -> &'static str {
34 match self {
35 Dignity::Rulership => "+",
36 Dignity::Exaltation => "·",
37 Dignity::Detriment => "−",
38 Dignity::Fall => "*",
39 }
40 }
41}
42
43/// Devuelve el status de dignidad de `body` en `sign_index` (0..12,
44/// Aries=0) o `None` si no aplica (sin dignidad / cuerpo moderno sin
45/// regencia clásica).
46pub fn essential_dignity(body: Body, sign_index: u8) -> Option<Dignity> {
47 let sign = sign_index % 12;
48 let opposite = (sign + 6) % 12;
49
50 // Rulership clásico — el "regente" del signo.
51 if rules_classical(body, sign) {
52 return Some(Dignity::Rulership);
53 }
54 // Detriment = el cuerpo gobierna el signo opuesto.
55 if rules_classical(body, opposite) {
56 return Some(Dignity::Detriment);
57 }
58 // Exaltación tabular.
59 if exalts_at(body) == Some(sign) {
60 return Some(Dignity::Exaltation);
61 }
62 // Caída = opuesto a la exaltación.
63 if exalts_at(body) == Some(opposite) {
64 return Some(Dignity::Fall);
65 }
66 None
67}
68
69/// Devuelve true si `body` gobierna `sign` (0=Aries..11=Pisces) en el
70/// esquema clásico de 7 planetas.
71fn rules_classical(body: Body, sign: u8) -> bool {
72 match (body, sign) {
73 // Sol: Leo (4)
74 (Body::Sun, 4) => true,
75 // Luna: Cancer (3)
76 (Body::Moon, 3) => true,
77 // Mercurio: Gemini (2), Virgo (5)
78 (Body::Mercury, 2) | (Body::Mercury, 5) => true,
79 // Venus: Taurus (1), Libra (6)
80 (Body::Venus, 1) | (Body::Venus, 6) => true,
81 // Marte: Aries (0), Scorpio (7)
82 (Body::Mars, 0) | (Body::Mars, 7) => true,
83 // Júpiter: Sagittarius (8), Pisces (11)
84 (Body::Jupiter, 8) | (Body::Jupiter, 11) => true,
85 // Saturno: Capricorn (9), Aquarius (10)
86 (Body::Saturn, 9) | (Body::Saturn, 10) => true,
87 _ => false,
88 }
89}
90
91/// Devuelve el signo (0..12) donde el cuerpo exalta, o `None` si no
92/// tiene exaltación clásica documentada.
93fn exalts_at(body: Body) -> Option<u8> {
94 Some(match body {
95 Body::Sun => 0, // Aries
96 Body::Moon => 1, // Taurus
97 Body::Mercury => 5, // Virgo (algunas tradiciones la ponen acá)
98 Body::Venus => 11, // Pisces
99 Body::Mars => 9, // Capricorn
100 Body::Jupiter => 3, // Cancer
101 Body::Saturn => 6, // Libra
102 _ => return None,
103 })
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[test]
111 fn rulership_examples() {
112 assert_eq!(essential_dignity(Body::Sun, 4), Some(Dignity::Rulership)); // Sol en Leo
113 assert_eq!(essential_dignity(Body::Moon, 3), Some(Dignity::Rulership)); // Luna en Cancer
114 assert_eq!(essential_dignity(Body::Mars, 7), Some(Dignity::Rulership)); // Marte en Scorpio
115 }
116
117 #[test]
118 fn detriment_examples() {
119 assert_eq!(essential_dignity(Body::Sun, 10), Some(Dignity::Detriment)); // Sol en Acuario
120 assert_eq!(essential_dignity(Body::Moon, 9), Some(Dignity::Detriment)); // Luna en Capricornio
121 }
122
123 #[test]
124 fn exaltation_examples() {
125 assert_eq!(essential_dignity(Body::Sun, 0), Some(Dignity::Exaltation)); // Sol en Aries
126 assert_eq!(essential_dignity(Body::Saturn, 6), Some(Dignity::Exaltation)); // Saturno en Libra
127 }
128
129 #[test]
130 fn fall_examples() {
131 assert_eq!(essential_dignity(Body::Sun, 6), Some(Dignity::Fall)); // Sol en Libra
132 assert_eq!(essential_dignity(Body::Saturn, 0), Some(Dignity::Fall)); // Saturno en Aries
133 }
134
135 #[test]
136 fn modern_planets_no_classical_dignity() {
137 assert_eq!(essential_dignity(Body::Uranus, 10), None);
138 assert_eq!(essential_dignity(Body::Neptune, 11), None);
139 assert_eq!(essential_dignity(Body::Pluto, 7), None);
140 }
141}