Translation

Two-way lookup between keys and translations, plus the per-category translation functions.

Every field on a chart already carries both a translation and a *_key, so manual translation is usually unnecessary. These functions exist for the cases where you have only a key (or only a translation in some language) and need to convert.

Six languages are supported: zh-CN, zh-TW, en-US, ja-JP, ko-KR, vi-VN.


translate_key

Purpose Translate any key into a given language.

Signature

pub fn translate_key(key: &str, lang: Language) -> Option<&'static str>

Parameters

ParameterTypeRequiredDefaultDescription
key&strYesA language-independent key
langLanguageYesTarget language

Covering 260 keys across twelve categories:

CategoryCountExamples
Stars162ziweiMaj, changsheng, yunlu
Palaces (including the body and original palaces)14soulPalace, wealthPalace, bodyPalace, originalPalace
Heavenly stems10jiaHeavenly
Earthly branches12ziEarthly
Brightness7miao, wang
Mutagens4sihuaLu
Five elements class5water2nd
Gender2male, female
Chinese zodiac12rat, ox
Hours13earlyRatHour
Zodiac signs12aries
Horoscope scopes7decadal, turn

Return value Option<&'static str>. An unknown key returns None.

Example

println!("{:?}", translate_key("ziweiMaj", Language::EnUS));
println!("{:?}", translate_key("soulPalace", Language::JaJP));
println!("{:?}", translate_key("nosuch", Language::ZhCN));

Output

Some("emperor")
Some("命宮")
None

key_of

Purpose Reverse-look-up a key from a translation in any language.

Signature

pub fn key_of(text: &str) -> Option<&'static str>
pub fn key_of_in(text: &str, key_filter: &str) -> Option<&'static str>

Parameters

ParameterTypeRequiredDefaultDescription
text&strYesA translation in any supported language
key_filter&strYesA substring the key name must contain, for disambiguating homographic translations

Return value Option<&'static str>. None when nothing matches.

Example

println!("{:?}", key_of("紫微"));
println!("{:?}", key_of("emperor"));
println!("{:?}", key_of("자미"));
println!("{:?}", key_of("no such name"));

Output

Some("ziweiMaj")
Some("ziweiMaj")
Some("ziweiMaj")
None

Translations in all three languages resolve to the same key.

Edge cases and pitfalls


all_keys

Purpose Get all 260 translatable keys.

Signature

pub fn all_keys() -> Vec<&'static str>

Return value Vec<&'static str>, in the order key_of scans them: horoscope scopes, Chinese zodiac, hours, zodiac signs, five elements classes, heavenly stems, earthly branches, brightness, mutagens, stars, palaces, gender — matching the merge order of iztro's per-language translation files.

Example

use x_iztro::i18n::lookup::{all_keys, translate_key};

let keys = all_keys();
println!("{} keys", keys.len());
println!("{:?}", &keys[..4]);
println!("{:?}", translate_key(keys[0], Language::EnUS));

Output

260 keys
["decadal", "childhood", "yearly", "monthly"]
Some("decadal")

To iterate the keys of one category, the matching constant in the data module (ALL_STARS, PALACES, HEAVENLY_STEMS, MUTAGEN and so on) is simpler.


Per-category translation functions

When the category of a key is known, the matching strongly typed function is more direct and drops the Option.

FunctionInput
translate_starStarKey
translate_palacePalace
translate_heavenly_stemHeavenlyStem
translate_earthly_branchEarthlyBranch
translate_brightnessBrightness
translate_mutagenMutagen
translate_five_elements_classFiveElementsClass
translate_genderGender
translate_zodiacEarthlyBranch
translate_timeu8 (hour index 0–12)
translate_signusize (sign index 0–11, from Aries)
translate_horoscope_nameHoroscopeName

All take the form fn(value, Language) -> &'static str and return static strings without allocating. All twelve are re-exported at the crate root, so use x_iztro::*; brings them in.

Example

use x_iztro::i18n::{translate_palace, translate_star};

println!("{}", translate_star(StarKey::ZiweiMaj, Language::ViVN));
println!("{}", translate_palace(Palace::Soul, Language::KoKR));

Output

Tử Vi
명궁

There is no global language switch

x-iztro keeps no global "current language" state: the language is passed as a parameter when charting, and translation functions name their target language explicitly on every call.

Why

A global language switch makes the same code produce different results depending on call order, which is especially dangerous with multiple threads. Passing it explicitly means a call's result depends only on its arguments.

To emit several languages within one process, just chart several times or call the translation functions repeatedly; they do not interfere:

let en = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;
let zh = by_solar("2000-8-16", 2, Gender::Female, true, Language::ZhCN, Config::default())?;

println!("{} / {}", en.palace(Palace::Soul).unwrap().major_stars[0].name,
                    zh.palace(Palace::Soul).unwrap().major_stars[0].name);

Output

emperor / 紫微

On this page