diff --git a/Cargo.lock b/Cargo.lock index f8076ea..f901185 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1789,7 +1789,6 @@ version = "0.1.0" dependencies = [ "csv", "glob", - "lazy_static", "multimap", "vidyut-chandas", "vidyut-cheda", @@ -1805,7 +1804,6 @@ name = "vidyut-chandas" version = "0.1.0" dependencies = [ "console_error_panic_hook", - "lazy_static", "serde", "serde-wasm-bindgen", "serde_derive", @@ -1819,7 +1817,6 @@ dependencies = [ "clap", "compact_str 0.8.1", "env_logger", - "lazy_static", "log", "priority-queue", "regex", @@ -1891,7 +1888,6 @@ dependencies = [ "csv", "enumset", "flate2", - "lazy_static", "rayon", "rmp-serde", "rustc-hash", @@ -1924,7 +1920,6 @@ dependencies = [ "clap", "compact_str 0.7.1", "csv", - "lazy_static", "rustc-hash", "tempfile", ] diff --git a/Cargo.toml b/Cargo.toml index 52ae845..eb5c817 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ vidyut-prakriya = { path = "./vidyut-prakriya" } vidyut-sandhi = { path = "./vidyut-sandhi" } csv = "1.1.6" multimap = "0.8.3" -lazy_static = "1.4.0" glob = "0.3.1" [workspace.dependencies] diff --git a/bindings-python/Cargo.lock b/bindings-python/Cargo.lock index 559bfe4..d9d24f7 100644 --- a/bindings-python/Cargo.lock +++ b/bindings-python/Cargo.lock @@ -727,7 +727,6 @@ name = "vidyut-chandas" version = "0.1.0" dependencies = [ "console_error_panic_hook", - "lazy_static", "serde", "serde-wasm-bindgen", "serde_derive", @@ -811,7 +810,6 @@ dependencies = [ "clap", "compact_str 0.7.1", "csv", - "lazy_static", "rustc-hash", ] diff --git a/vidyut-chandas/Cargo.toml b/vidyut-chandas/Cargo.toml index 0c8c4bd..100a528 100644 --- a/vidyut-chandas/Cargo.toml +++ b/vidyut-chandas/Cargo.toml @@ -12,7 +12,6 @@ edition = "2021" [dependencies] console_error_panic_hook = "0.1.7" -lazy_static = "1.4.0" serde = { version = "1.0.150", features = ["derive"] } serde-wasm-bindgen = "0.4" serde_derive = "1.0.193" diff --git a/vidyut-chandas/src/sounds.rs b/vidyut-chandas/src/sounds.rs index 8927be4..848e66b 100644 --- a/vidyut-chandas/src/sounds.rs +++ b/vidyut-chandas/src/sounds.rs @@ -1,10 +1,8 @@ -use lazy_static::lazy_static; +use std::sync::OnceLock; -lazy_static! { - static ref HRASVA: Set = Set::from("aiufx"); - static ref AC: Set = Set::from("aAiIuUfFxXeEoO"); - static ref HAL: Set = Set::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL"); -} +static HRASVA: OnceLock = OnceLock::new(); +static AC: OnceLock = OnceLock::new(); +static HAL: OnceLock = OnceLock::new(); type Sound = char; @@ -37,22 +35,23 @@ impl Set { /// Returns whether `c` is a vowel. pub(crate) fn is_ac(c: Sound) -> bool { - AC.contains(c) + AC.get_or_init(|| Set::from("aAiIuUfFxXeEoO")).contains(c) } /// Returns whether `c` is a short vowel. pub(crate) fn is_hrasva(c: Sound) -> bool { - HRASVA.contains(c) + HRASVA.get_or_init(|| Set::from("aiufx")).contains(c) } /// Returns whether `c` is a consonant. pub(crate) fn is_hal(c: Sound) -> bool { - HAL.contains(c) + HAL.get_or_init(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL")) + .contains(c) } /// Returns whether `c` is a Sanskrit sound. pub(crate) fn is_sanskrit(c: Sound) -> bool { - AC.contains(c) || HAL.contains(c) || matches!(c, 'M' | 'H') + is_ac(c) || is_hal(c) || matches!(c, 'M' | 'H') } /// Returns whether `s` starts with a consonant cluster. diff --git a/vidyut-cheda/Cargo.toml b/vidyut-cheda/Cargo.toml index 0a10174..bef858e 100644 --- a/vidyut-cheda/Cargo.toml +++ b/vidyut-cheda/Cargo.toml @@ -13,7 +13,6 @@ compact_str = "0.8.1" clap = { workspace = true } log = { workspace = true } env_logger = { workspace = true } -lazy_static = "1.5.0" regex = "1.11.1" rmp-serde = { workspace = true } serde = {workspace = true } diff --git a/vidyut-cheda/src/normalize_text.rs b/vidyut-cheda/src/normalize_text.rs index 06daa54..9e0eccf 100644 --- a/vidyut-cheda/src/normalize_text.rs +++ b/vidyut-cheda/src/normalize_text.rs @@ -1,4 +1,5 @@ -use lazy_static::lazy_static; +use std::sync::OnceLock; + use regex::Regex; /// Creates a normalized version of `text` that is easier to process. @@ -8,12 +9,12 @@ use regex::Regex; /// 2. Delete all whitespace spans. /// 3. Separate all remaining spans with a single " ". pub fn normalize(text: &str) -> String { - lazy_static! { - static ref RE: Regex = - Regex::new(r"([a-zA-Z']+)|(\s+)|([^a-zA-Z']+)").expect("always defined"); - } + static RE: OnceLock = OnceLock::new(); + + let re = + RE.get_or_init(|| Regex::new(r"([a-zA-Z']+)|(\s+)|([^a-zA-Z']+)").expect("always defined")); - let mut ret = RE + let mut ret = re .find_iter(text) .map(|m| m.as_str()) .filter(|s| !s.trim().is_empty()) diff --git a/vidyut-cheda/src/sounds.rs b/vidyut-cheda/src/sounds.rs index 88fe105..b433141 100644 --- a/vidyut-cheda/src/sounds.rs +++ b/vidyut-cheda/src/sounds.rs @@ -1,6 +1,6 @@ //! Utility functions for checking Sanskrit sounds. -use lazy_static::lazy_static; +use std::sync::OnceLock; /// A set of Sanskrit sounds. /// @@ -42,21 +42,19 @@ impl Default for SoundSet { /// - other punctuation characters (|, ||, numbers) /// - characters or symbols from non-SLP1 encodings pub fn is_sanskrit(c: char) -> bool { - lazy_static! { - static ref CHARS: SoundSet = - SoundSet::from("aAiIuUfFxXeEoOMHkKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL'"); - } - CHARS.contains(c) + static CHARS: OnceLock = OnceLock::new(); + let chars = + CHARS.get_or_init(|| SoundSet::from("aAiIuUfFxXeEoOMHkKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL'")); + chars.contains(c) } /// Returns whether the given sound is a vowel. /// /// `ac` is the Paninian name for the Sanskrit vowels. pub fn is_ac(c: char) -> bool { - lazy_static! { - static ref AC: SoundSet = SoundSet::from("aAiIuUfFxXeEoO"); - } - AC.contains(c) + static AC: OnceLock = OnceLock::new(); + let ac = AC.get_or_init(|| SoundSet::from("aAiIuUfFxXeEoO")); + ac.contains(c) } /// Returns whether the given sound is a consonant. @@ -64,19 +62,19 @@ pub fn is_ac(c: char) -> bool { /// `hal` is the Paninian name for the Sanskrit consonants. #[allow(unused)] pub fn is_hal(c: char) -> bool { - lazy_static! { - static ref HAL: SoundSet = SoundSet::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL"); - } - HAL.contains(c) + static HAL: OnceLock = OnceLock::new(); + + let hal = HAL.get_or_init(|| SoundSet::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL")); + hal.contains(c) } /// Returns whether the given sound is voiced. #[allow(unused)] pub fn is_ghosha(c: char) -> bool { - lazy_static! { - static ref GHOSHA: SoundSet = SoundSet::from("aAiIuUfFxXeEoOgGNjJYqQRdDnbBmyrlvh"); - } - GHOSHA.contains(c) + static GHOSHA: OnceLock = OnceLock::new(); + + let ghosha = GHOSHA.get_or_init(|| SoundSet::from("aAiIuUfFxXeEoOgGNjJYqQRdDnbBmyrlvh")); + ghosha.contains(c) } #[cfg(test)] diff --git a/vidyut-prakriya/Cargo.lock b/vidyut-prakriya/Cargo.lock index 6c9e9f0..94bf432 100644 --- a/vidyut-prakriya/Cargo.lock +++ b/vidyut-prakriya/Cargo.lock @@ -542,7 +542,6 @@ dependencies = [ "compact_str", "csv", "enumset", - "lazy_static", "serde", "sha2 0.10.6", "sha256", diff --git a/vidyut-prakriya/Cargo.toml b/vidyut-prakriya/Cargo.toml index 968df6d..caf83b5 100644 --- a/vidyut-prakriya/Cargo.toml +++ b/vidyut-prakriya/Cargo.toml @@ -13,10 +13,9 @@ rust-version = "1.68" [dependencies] enumset = { version = "1.1.3", features = ["serde"] } -lazy_static = "1.4.0" rustc-hash = { workspace = true } serde = { version = "1.0.150", features = ["derive"] } -wasm-bindgen = { version = "0.2", features = ["serde-serialize"]} +wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } serde-wasm-bindgen = "0.4" console_error_panic_hook = "0.1.7" diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index 70078f3..712b87a 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -6,6 +6,8 @@ abhyasasya Runs rules that modify the abhyāsa. */ +use std::sync::OnceLock; + use crate::args::Agama as A; use crate::args::Agama; use crate::args::Aupadeshika; @@ -23,7 +25,6 @@ use crate::dhatu_gana as gana; use crate::it_samjna; use crate::sounds as al; use crate::sounds::{map, s, Map, Set, AC, HAL}; -use lazy_static::lazy_static; const AA: Set = s(&["a"]); const ANUNASIKA: Set = s(&["Yam"]); @@ -33,9 +34,7 @@ const KHAY: Set = s(&["Kay"]); const F_HAL: Set = s(&["f hal"]); const PU_YAN_J: Set = s(&["pu~", "yaR", "j"]); -lazy_static! { - static ref KUH_CU: Map = map("ku~ h", "cu~"); -} +static KUH_CU: OnceLock = OnceLock::new(); /// Simplifies the abhyasa per 7.4.60. fn try_haladi(text: &str) -> TermString { @@ -269,7 +268,10 @@ fn try_general_rules(p: &mut Prakriya, i: usize) -> Option<()> { let abhyasa = p.get(i)?; let dhatu = p.get(i_dhatu)?; - if let Some(val) = KUH_CU.get(abhyasa.adi()?) { + if let Some(val) = KUH_CU + .get_or_init(|| map("ku~ h", "cu~")) + .get(abhyasa.adi()?) + { let n = p.get(i_dhatu + 1)?; if dhatu.has_u("ku\\N") && dhatu.has_gana(Gana::Bhvadi) && n.is(S::yaN) { p.step("7.4.63"); diff --git a/vidyut-prakriya/src/krt/basic.rs b/vidyut-prakriya/src/krt/basic.rs index 7726028..73dcd3f 100644 --- a/vidyut-prakriya/src/krt/basic.rs +++ b/vidyut-prakriya/src/krt/basic.rs @@ -70,15 +70,13 @@ use crate::krt::utils::KrtPrakriya; use crate::sounds::{s, Set, AC, HAL, IK}; use crate::stem_gana::TYAD_ADI; use crate::Rule::Varttika; -use lazy_static::lazy_static; +use std::sync::OnceLock; const II: Set = s(&["i"]); const UU: Set = s(&["u"]); const PU: Set = s(&["pu~"]); -lazy_static! { - static ref EMPTY_TERM: Term = Term::make_text(""); -} +static EMPTY_TERM: OnceLock = OnceLock::new(); /// Tries to add various pratyayas that are just "a." fn try_add_various_pratyayas(kp: &mut KrtPrakriya) { @@ -563,7 +561,7 @@ fn try_add_upapada_krt(kp: &mut KrtPrakriya) -> Option { let upapada = match kp.p.get_if(0, |t| t.has_tag(T::Pratipadika)) { Some(t) => t, - None => &EMPTY_TERM, + None => &EMPTY_TERM.get_or_init(|| Term::make_text("")), }; let upapade = kp.p.has(0, |t| t.has_tag(T::Pratipadika)); diff --git a/vidyut-prakriya/src/sounds.rs b/vidyut-prakriya/src/sounds.rs index 991b2ae..0d8b099 100644 --- a/vidyut-prakriya/src/sounds.rs +++ b/vidyut-prakriya/src/sounds.rs @@ -34,9 +34,8 @@ We chose SLP1 over something like [WX][wx] merely because we have more familiari [slp1]: https://en.wikipedia.org/wiki/SLP1 [wx]: https://en.wikipedia.org/wiki/WX_notation */ -use lazy_static::lazy_static; use rustc_hash::FxHashMap; -use std::fmt; +use std::{fmt, sync::OnceLock}; type Sound = char; @@ -49,9 +48,7 @@ pub const HAL: Set = s(&["hal"]); pub const YAN: Set = s(&["yaR"]); pub const VAL: Set = s(&["val"]); -lazy_static! { - static ref SOUND_PROPS: FxHashMap = create_sound_props(); -} +static SOUND_PROPS: OnceLock> = OnceLock::new(); /// A set of Sanskrit sounds. /// @@ -636,17 +633,18 @@ pub const fn savarna(c: Sound) -> Set { pub(crate) fn map(keys: &str, values: &str) -> Map { let keys = s_old(keys); let values = s_old(values); + let sound_props = SOUND_PROPS.get_or_init(|| create_sound_props()); let mut map = Map::new(); for key in keys.to_string().chars() { - let key_props = SOUND_PROPS.get(&key).expect("called statically"); + let key_props = sound_props.get(&key).expect("called statically"); // The best sound has the minimal distance. let best_value = values .to_string() .chars() .min_by_key(|v| { - SOUND_PROPS + sound_props .get(v) .expect("called statically") .distance(key_props) diff --git a/vidyut-prakriya/src/tripadi/pada_8_2.rs b/vidyut-prakriya/src/tripadi/pada_8_2.rs index ce4e58b..2a561da 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_2.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_2.rs @@ -1,3 +1,5 @@ +use std::sync::OnceLock; + use crate::args::Agama as A; use crate::args::Aupadeshika as Au; use crate::args::BaseKrt as K; @@ -16,7 +18,6 @@ use crate::dhatu_gana; use crate::ganapatha; use crate::sounds as al; use crate::sounds::{map, s, Map, Set, AC, HAL, IK, JHAL}; -use lazy_static::lazy_static; const YAN: Set = s(&["yaR"]); const CU: Set = s(&["cu~"]); @@ -25,11 +26,9 @@ const BASH: Set = s(&["baS"]); const JHAL_TO_JASH_EXCEPTIONS: Set = Set::from("cSsh"); const HASH: Set = s(&["haS"]); -lazy_static! { - static ref BASH_TO_BHAZ: Map = map("baS", "Baz"); - static ref JHAL_TO_JASH: Map = map("Jal", "jaS"); - static ref CU_TO_KU: Map = map("cu~", "ku~"); -} +static BASH_TO_BHAZ: OnceLock = OnceLock::new(); +static JHAL_TO_JASH: OnceLock = OnceLock::new(); +static CU_TO_KU: OnceLock = OnceLock::new(); fn do_ru_adesha(rule: impl Into, p: &mut Prakriya, i: usize) { p.run_at(rule, i, |t| { @@ -456,7 +455,7 @@ fn per_term_1a(p: &mut Prakriya) -> Option<()> { if x.has_antya(CU) && (is_jhali || is_ante) { if let Some(c) = x.antya() { - let sub = CU_TO_KU.get(c)?; + let sub = CU_TO_KU.get_or_init(|| map("cu~", "ku~")).get(c)?; p.run_at("8.2.30", i, |t| { // TODO: what is the rule that allows this change? if t.has_upadha('Y') { @@ -491,7 +490,9 @@ fn per_term_1b(p: &mut Prakriya) -> Option<()> { }; if x.has_adi(BASH) && x.has_antya(JHAZ) && x.is_ekac() && x.is_dhatu() && if_y { - let sub = BASH_TO_BHAZ.get(x.adi()?)?; + let sub = BASH_TO_BHAZ + .get_or_init(|| map("baS", "Baz")) + .get(x.adi()?)?; p.run_at("8.2.37", i, |t| t.set_adi_char(sub)); } } @@ -516,7 +517,7 @@ fn per_term_1b(p: &mut Prakriya) -> Option<()> { && !t.has_tag_in(&[T::FlagAntyaAcSandhi, T::FlagPratipadikaTiLopa]) { let key = t.antya()?; - let sub = JHAL_TO_JASH.get(key)?; + let sub = JHAL_TO_JASH.get_or_init(|| map("Jal", "jaS")).get(key)?; p.run_at("8.2.39", i, |t| t.set_antya_char(sub)); } } diff --git a/vidyut-prakriya/src/tripadi/pada_8_4.rs b/vidyut-prakriya/src/tripadi/pada_8_4.rs index ddb13c5..23329aa 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_4.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_4.rs @@ -1,3 +1,5 @@ +use std::sync::OnceLock; + use crate::args::Aupadeshika as Au; use crate::args::Gana; use crate::args::Lakara::*; @@ -10,7 +12,6 @@ use crate::core::Rule::Varttika; use crate::core::{Prakriya, Rule, Tag as T, Term}; use crate::sounds as al; use crate::sounds::{map, s, Map, Set, AC, HAL, JHAL}; -use lazy_static::lazy_static; const AT_KU_PU_M: Set = s(&["aw", "ku~", "pu~", "M"]); const AA: Set = s(&["a"]); @@ -27,11 +28,9 @@ const YAY: Set = s(&["yay"]); const JHAY: Set = s(&["Jay"]); const AT: Set = s(&["aw"]); -lazy_static! { - static ref JHAL_TO_CAR: Map = map("Jal", "car"); - static ref JHAL_TO_JASH: Map = map("Jal", "jaS"); - static ref JHAL_TO_JASH_CAR: Map = map("Jal", "jaS car"); -} +static JHAL_TO_CAR: OnceLock = OnceLock::new(); +static JHAL_TO_JASH: OnceLock = OnceLock::new(); +static JHAL_TO_JASH_CAR: OnceLock = OnceLock::new(); /// Runs rules that change `n` to `R`. /// Example: krInAti -> krIRAti. @@ -378,7 +377,7 @@ fn try_jhal_adesha(ip: &mut IndexPrakriya) -> Option<()> { let x = ip.char_at(&i_x); let y = ip.char_at(i_y); - let sub = JHAL_TO_JASH.get(x); + let sub = JHAL_TO_JASH.get_or_init(|| map("Jal", "jaS")).get(x); if sub.is_some() && JHASH.contains(y) { let sub = sub.expect("present"); if x != sub { @@ -393,7 +392,10 @@ fn try_jhal_adesha(ip: &mut IndexPrakriya) -> Option<()> { // Check for jaz-car to avoid applying a rule that causes no changee. if x.is_abhyasa() && x.has_adi(JHAL) && !x.has_adi(JASH_CAR) { - let sub = JHAL_TO_JASH_CAR.get(x.adi().expect("ok")).expect("ok"); + let sub = JHAL_TO_JASH_CAR + .get_or_init(|| map("Jal", "jaS car")) + .get(x.adi().expect("ok")) + .expect("ok"); ip.p.run_at("8.4.54", i, |t| t.set_adi_char(sub)); } @@ -425,8 +427,9 @@ fn try_jhal_adesha(ip: &mut IndexPrakriya) -> Option<()> { let i_x = ip.prev(i_y)?; let x = ip.char_at(&i_x); let y = ip.char_at(i_y); + let sub = JHAL_TO_CAR.get_or_init(|| map("Jal", "car")).get(x); - if let Some(sub) = JHAL_TO_CAR.get(x) { + if let Some(sub) = sub { if KHAR.contains(y) { if x != sub { ip.run_for_char("8.4.55", &i_x, &sub.to_string()); @@ -438,7 +441,8 @@ fn try_jhal_adesha(ip: &mut IndexPrakriya) -> Option<()> { ip.iter(|ip, i_x| { let x = ip.char_at(i_x); - let sub = JHAL_TO_CAR.get(x); + let sub = JHAL_TO_CAR.get_or_init(|| map("Jal", "car")).get(x); + if let Some(sub) = sub { let last = ip.p.terms().last()?; if x != sub { diff --git a/vidyut-prakriya/tests/integration/kashika_1_1.rs b/vidyut-prakriya/tests/integration/kashika_1_1.rs index 4ccdc20..30e13c5 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_1.rs @@ -1,5 +1,6 @@ extern crate test_utils; -use lazy_static::lazy_static; +use std::sync::OnceLock; + use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; @@ -10,9 +11,7 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; -lazy_static! { - static ref S: Tester = Tester::with_svara_rules(); -} +static S: OnceLock = OnceLock::new(); #[test] fn sutra_1_1_1() { @@ -271,8 +270,10 @@ fn sutra_1_1_20() { #[test] fn sutra_1_1_21() { - S.assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::tavya, &["karta/vya"]); - S.assert_has_taddhita("upagu", T::aR, &["Opagava/"]); + let s = S.get_or_init(|| Tester::with_svara_rules()); + + s.assert_has_krdanta(&[], &d("qukf\\Y", Tanadi), Krt::tavya, &["karta/vya"]); + s.assert_has_taddhita("upagu", T::aR, &["Opagava/"]); assert_has_sup_3d("vfkza", Pum, &["vfkzAByAm"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_3_1.rs b/vidyut-prakriya/tests/integration/kashika_3_1.rs index 48541af..02409b6 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_1.rs @@ -1,5 +1,6 @@ extern crate test_utils; -use lazy_static::lazy_static; +use std::sync::OnceLock; + use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; @@ -9,9 +10,7 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha as TA; use vidyut_prakriya::args::*; -lazy_static! { - static ref S: Tester = Tester::with_svara_rules(); -} +static S: OnceLock = OnceLock::new(); fn sanadi(p: Pratipadika, s: Sanadi) -> Dhatu { Dhatu::nama(p, Some(s)) @@ -38,19 +37,21 @@ fn sutra_3_1_2() { #[test] fn sutra_3_1_3() { let kf = d("qukf\\Y", Tanadi); - S.assert_has_krdanta(&[], &kf, Krt::tavyat, &["kartavya^"]); - S.assert_has_artha_taddhita("tittiri", TA::TenaProktam, T::CaR, &["tEttirI/ya"]); + let s = S.get_or_init(|| Tester::with_svara_rules()); + s.assert_has_krdanta(&[], &kf, Krt::tavyat, &["kartavya^"]); + s.assert_has_artha_taddhita("tittiri", TA::TenaProktam, T::CaR, &["tEttirI/ya"]); } #[test] fn sutra_3_1_4() { + let s = S.get_or_init(|| Tester::with_svara_rules()); // sup - S.assert_has_sup_1d("dfzad", Pum, &["dfza/dO"]); - S.assert_has_sup_1p("dfzad", Pum, &["dfza/daH"]); + s.assert_has_sup_1d("dfzad", Pum, &["dfza/dO"]); + s.assert_has_sup_1p("dfzad", Pum, &["dfza/daH"]); // pit - S.assert_has_tip(&[], &d("qupa\\ca~^z", Bhvadi), Lat, &["pa/cati"]); - S.assert_has_tip(&[], &d("paWa~", Bhvadi), Lat, &["pa/Wati"]); + s.assert_has_tip(&[], &d("qupa\\ca~^z", Bhvadi), Lat, &["pa/cati"]); + s.assert_has_tip(&[], &d("paWa~", Bhvadi), Lat, &["pa/Wati"]); } #[test] diff --git a/vidyut-prakriya/tests/integration/kashika_6_1.rs b/vidyut-prakriya/tests/integration/kashika_6_1.rs index c6b6c12..773b857 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_1.rs @@ -1,5 +1,6 @@ extern crate test_utils; -use lazy_static::lazy_static; +use std::sync::OnceLock; + use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; use vidyut_prakriya::args::Gana::*; @@ -9,8 +10,10 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::*; -lazy_static! { - static ref S: Tester = Tester::with_svara_rules(); +static S: OnceLock = OnceLock::new(); + +fn get_tester() -> &'static Tester { + S.get_or_init(|| Tester::with_svara_rules()) } #[test] @@ -1134,174 +1137,193 @@ fn sutra_6_1_141() { #[test] fn sutra_6_1_159() { - S.assert_has_krdanta(&[], &d("kf\\za~", Bhvadi), Krt::GaY, &["karza/"]); + let s = get_tester(); + s.assert_has_krdanta(&[], &d("kf\\za~", Bhvadi), Krt::GaY, &["karza/"]); } #[ignore] #[test] fn sutra_6_1_162() { - S.assert_has_tip(&[], &d("qupa\\ca~^z", Bhvadi), Lat, &["pa/cati"]); - S.assert_has_tip(&[], &d("paWa~", Bhvadi), Lat, &["pa/Wati"]); - S.assert_has_tip(&[], &d("UrRuY", Adadi), Lat, &["UrRo/ti", "UrRO/ti"]); - S.assert_has_tip(&[], &d("gupU~", Bhvadi), Lat, &["gopAya/ti"]); - S.assert_has_tip(&[], &d("yA\\", Adadi), Lat, &["yA/ti"]); + let s = get_tester(); + s.assert_has_tip(&[], &d("qupa\\ca~^z", Bhvadi), Lat, &["pa/cati"]); + s.assert_has_tip(&[], &d("paWa~", Bhvadi), Lat, &["pa/Wati"]); + s.assert_has_tip(&[], &d("UrRuY", Adadi), Lat, &["UrRo/ti", "UrRO/ti"]); + s.assert_has_tip(&[], &d("gupU~", Bhvadi), Lat, &["gopAya/ti"]); + s.assert_has_tip(&[], &d("yA\\", Adadi), Lat, &["yA/ti"]); } #[test] fn sutra_6_1_163() { - S.assert_has_krdanta(&[], &d("Ba\\njo~", Rudhadi), Krt::Gurac, &["BaNgura/"]); - S.assert_has_krdanta(&[], &d("BAsf~\\", Bhvadi), Krt::Gurac, &["BAsura/"]); - S.assert_has_krdanta(&[], &d("YimidA~", Divadi), Krt::Gurac, &["medura/"]); + let s = get_tester(); + s.assert_has_krdanta(&[], &d("Ba\\njo~", Rudhadi), Krt::Gurac, &["BaNgura/"]); + s.assert_has_krdanta(&[], &d("BAsf~\\", Bhvadi), Krt::Gurac, &["BAsura/"]); + s.assert_has_krdanta(&[], &d("YimidA~", Divadi), Krt::Gurac, &["medura/"]); // TODO: others } #[test] fn sutra_6_1_164() { - S.assert_has_artha_taddhita("kuYja", Gotra, T::cPaY, &["kOYjAyana/"]); + let s = get_tester(); + s.assert_has_artha_taddhita("kuYja", Gotra, T::cPaY, &["kOYjAyana/"]); // TODO: where is this from? // S.assert_has_artha_taddhita("muYja", Gotra, T::cPaY, &["mOYjAyana/"]); } #[test] fn sutra_6_1_165() { - S.assert_has_artha_taddhita("naqa", Gotra, T::Pak, &["nAqAyana/"]); - S.assert_has_artha_taddhita("cara", Gotra, T::Pak, &["cArAyaRa/"]); - S.assert_has_artha_taddhita("akza", TenaDivyatiJayatiJitam, T::Wak, &["Akzika/"]); + let s = get_tester(); + s.assert_has_artha_taddhita("naqa", Gotra, T::Pak, &["nAqAyana/"]); + s.assert_has_artha_taddhita("cara", Gotra, T::Pak, &["cArAyaRa/"]); + s.assert_has_artha_taddhita("akza", TenaDivyatiJayatiJitam, T::Wak, &["Akzika/"]); } #[test] fn sutra_6_1_166() { - S.assert_has_sup_1p("tri", Stri, &["tisra/H"]); + let s = get_tester(); + s.assert_has_sup_1p("tri", Stri, &["tisra/H"]); } #[test] fn sutra_6_1_167() { - S.assert_has_sup_2p("catur", Pum, &["catu/raH"]); + let s = get_tester(); + s.assert_has_sup_2p("catur", Pum, &["catu/raH"]); } #[test] fn sutra_6_1_179() { - S.assert_has_sup_3p("zaz", Pum, &["zaqBi/H"]); - S.assert_has_sup_4p("zaz", Pum, &["zaqBya/H"]); - S.assert_has_sup_6p("paYcan", Pum, &["paYcAnA/m"]); - S.assert_has_sup_6p("zaz", Pum, &["zaRRA/m"]); - S.assert_has_sup_6p("saptan", Pum, &["saptAnA/m"]); + let s = get_tester(); + s.assert_has_sup_3p("zaz", Pum, &["zaqBi/H"]); + s.assert_has_sup_4p("zaz", Pum, &["zaqBya/H"]); + s.assert_has_sup_6p("paYcan", Pum, &["paYcAnA/m"]); + s.assert_has_sup_6p("zaz", Pum, &["zaRRA/m"]); + s.assert_has_sup_6p("saptan", Pum, &["saptAnA/m"]); - S.assert_has_sup_3p("tri", Pum, &["triBi/H"]); - S.assert_has_sup_4p("tri", Pum, &["triBya/H"]); - S.assert_has_sup_6p("tri", Pum, &["trayARA/m"]); + s.assert_has_sup_3p("tri", Pum, &["triBi/H"]); + s.assert_has_sup_4p("tri", Pum, &["triBya/H"]); + s.assert_has_sup_6p("tri", Pum, &["trayARA/m"]); // TODO: caturByaH? - S.assert_has_sup_6p("catur", Pum, &["caturRA/m"]); + s.assert_has_sup_6p("catur", Pum, &["caturRA/m"]); // halAdiH? - S.assert_has_sup_2p("catur", Stri, &["cata/sraH"]); + s.assert_has_sup_2p("catur", Stri, &["cata/sraH"]); } #[test] fn sutra_6_1_180() { - S.assert_has_sup_3p("paYcan", Pum, &["paYca/BiH"]); - S.assert_has_sup_3p("saptan", Pum, &["sapta/BiH"]); - S.assert_has_sup_3p("tri", Stri, &["tisf/BiH"]); - S.assert_has_sup_3p("catur", Pum, &["catu/rBiH"]); + let s = get_tester(); + s.assert_has_sup_3p("paYcan", Pum, &["paYca/BiH"]); + s.assert_has_sup_3p("saptan", Pum, &["sapta/BiH"]); + s.assert_has_sup_3p("tri", Stri, &["tisf/BiH"]); + s.assert_has_sup_3p("catur", Pum, &["catu/rBiH"]); // Jali? - S.assert_has_sup_6p("paYcan", Pum, &["paYcAnA/m"]); - S.assert_has_sup_6p("saptan", Pum, &["saptAnA/m"]); + s.assert_has_sup_6p("paYcan", Pum, &["paYcAnA/m"]); + s.assert_has_sup_6p("saptan", Pum, &["saptAnA/m"]); // upottama? - S.assert_has_sup_3p("zaz", Pum, &["zaqBi/H"]); - S.assert_has_sup_4p("zaz", Pum, &["zaqBya/H"]); + s.assert_has_sup_3p("zaz", Pum, &["zaqBi/H"]); + s.assert_has_sup_4p("zaz", Pum, &["zaqBya/H"]); } #[test] fn sutra_6_1_183() { - S.assert_has_sup_3d("div", Pum, &["dyu/ByAm"]); - S.assert_has_sup_3p("div", Pum, &["dyu/BiH"]); + let s = get_tester(); + s.assert_has_sup_3d("div", Pum, &["dyu/ByAm"]); + s.assert_has_sup_3p("div", Pum, &["dyu/BiH"]); // Jal? - S.assert_has_sup_3s("div", Pum, &["di/vA"]); + s.assert_has_sup_3s("div", Pum, &["di/vA"]); } #[test] fn sutra_6_1_185() { let kr = d("qukf\\Y", Tanadi); let hr = d("hf\\Y", Bhvadi); - S.assert_has_krdanta(&[], &san(&kr), Krt::yat, &["cikIrzya^"]); - S.assert_has_krdanta(&[], &san(&hr), Krt::yat, &["jihIrzya^"]); - S.assert_has_krdanta(&[], &kr, Krt::Ryat, &["kArya^"]); - S.assert_has_krdanta(&[], &hr, Krt::Ryat, &["hArya^"]); + let s = get_tester(); + s.assert_has_krdanta(&[], &san(&kr), Krt::yat, &["cikIrzya^"]); + s.assert_has_krdanta(&[], &san(&hr), Krt::yat, &["jihIrzya^"]); + s.assert_has_krdanta(&[], &kr, Krt::Ryat, &["kArya^"]); + s.assert_has_krdanta(&[], &hr, Krt::Ryat, &["hArya^"]); } #[test] fn sutra_6_1_191() { - S.assert_has_sup_1s("sarva", Pum, &["sa/rvaH"]); - S.assert_has_sup_1d("sarva", Pum, &["sa/rvO"]); - S.assert_has_sup_1p("sarva", Pum, &["sa/rve"]); + let s = get_tester(); + s.assert_has_sup_1s("sarva", Pum, &["sa/rvaH"]); + s.assert_has_sup_1d("sarva", Pum, &["sa/rvO"]); + s.assert_has_sup_1p("sarva", Pum, &["sa/rve"]); } #[test] fn sutra_6_1_193() { let kr = d("qukf\\Y", Tanadi); let hr = d("hf\\Y", Bhvadi); - S.assert_has_krdanta(&[], &san(&kr), Krt::Rvul, &["cikI/rzaka"]); - S.assert_has_krdanta(&[], &san(&hr), Krt::Rvul, &["jihI/rzaka"]); + let s = get_tester(); + s.assert_has_krdanta(&[], &san(&kr), Krt::Rvul, &["cikI/rzaka"]); + s.assert_has_krdanta(&[], &san(&hr), Krt::Rvul, &["jihI/rzaka"]); - S.assert_has_taddhita("BOriki", T::viDal, &["BOriki/viDa"]); - S.assert_has_taddhita("BOliki", T::viDal, &["BOliki/viDa"]); - S.assert_has_taddhita("EzukAri", T::Baktal, &["EzukAri/Bakta"]); + s.assert_has_taddhita("BOriki", T::viDal, &["BOriki/viDa"]); + s.assert_has_taddhita("BOliki", T::viDal, &["BOliki/viDa"]); + s.assert_has_taddhita("EzukAri", T::Baktal, &["EzukAri/Bakta"]); } #[test] fn sutra_6_1_197() { - S.assert_has_taddhita("garga", T::yaY, &["gA/rgya"]); + let s = get_tester(); + s.assert_has_taddhita("garga", T::yaY, &["gA/rgya"]); } #[test] fn sutra_6_1_199() { - S.assert_has_sup_1s("paTin", Pum, &["pa/nTAH"]); - S.assert_has_sup_1d("paTin", Pum, &["pa/nTAnO"]); - S.assert_has_sup_1p("paTin", Pum, &["pa/nTAnaH"]); + let s = get_tester(); + s.assert_has_sup_1s("paTin", Pum, &["pa/nTAH"]); + s.assert_has_sup_1d("paTin", Pum, &["pa/nTAnO"]); + s.assert_has_sup_1p("paTin", Pum, &["pa/nTAnaH"]); - S.assert_has_sup_1s("maTin", Pum, &["ma/nTAH"]); - S.assert_has_sup_1d("maTin", Pum, &["ma/nTAnO"]); - S.assert_has_sup_1p("maTin", Pum, &["ma/nTAnaH"]); + s.assert_has_sup_1s("maTin", Pum, &["ma/nTAH"]); + s.assert_has_sup_1d("maTin", Pum, &["ma/nTAnO"]); + s.assert_has_sup_1p("maTin", Pum, &["ma/nTAnaH"]); // TODO: others } #[test] fn sutra_6_1_211() { - S.assert_has_sup_6s("yuzmad", Pum, &["ta/va"]); - S.assert_has_sup_6s("asmad", Pum, &["ma/ma"]); + let s = get_tester(); + s.assert_has_sup_6s("yuzmad", Pum, &["ta/va"]); + s.assert_has_sup_6s("asmad", Pum, &["ma/ma"]); } #[test] fn sutra_6_1_212() { - S.assert_has_sup_4s("yuzmad", Pum, &["tu/Byam"]); - S.assert_has_sup_4s("asmad", Pum, &["ma/hyam"]); + let s = get_tester(); + s.assert_has_sup_4s("yuzmad", Pum, &["tu/Byam"]); + s.assert_has_sup_4s("asmad", Pum, &["ma/hyam"]); } #[test] fn sutra_6_1_217() { let kr = d("qukf\\Y", Tanadi); let hr = d("hf\\Y", Bhvadi); - S.assert_has_krdanta(&[], &kr, Krt::anIyar, &["karaRI/ya"]); - S.assert_has_krdanta(&[], &hr, Krt::anIyar, &["haraRI/ya"]); + let s = get_tester(); + s.assert_has_krdanta(&[], &kr, Krt::anIyar, &["karaRI/ya"]); + s.assert_has_krdanta(&[], &hr, Krt::anIyar, &["haraRI/ya"]); - S.assert_has_taddhita("pawu", T::jAtIyar, &["pawujAtI/ya"]); - S.assert_has_taddhita("mfdu", T::jAtIyar, &["mfdujAtI/ya"]); + s.assert_has_taddhita("pawu", T::jAtIyar, &["pawujAtI/ya"]); + s.assert_has_taddhita("mfdu", T::jAtIyar, &["mfdujAtI/ya"]); } #[test] fn sutra_6_1_222() { let dadhyac = create_upapada_krdanta("daDyac", "daDi", &[], &d("ancu~", Bhvadi), Krt::kvin); - S.assert_has_sup_2p(&dadhyac, Pum, &["daDI/caH"]); - S.assert_has_sup_3s(&dadhyac, Pum, &["daDI/cA"]); - S.assert_has_sup_4s(&dadhyac, Pum, &["daDI/ce"]); + let s = get_tester(); + s.assert_has_sup_2p(&dadhyac, Pum, &["daDI/caH"]); + s.assert_has_sup_3s(&dadhyac, Pum, &["daDI/cA"]); + s.assert_has_sup_4s(&dadhyac, Pum, &["daDI/ce"]); let madhvac = create_upapada_krdanta("maDvac", "maDu", &[], &d("ancu~", Bhvadi), Krt::kvin); - S.assert_has_sup_2p(&madhvac, Pum, &["maDU/caH"]); - S.assert_has_sup_3s(&madhvac, Pum, &["maDU/cA"]); - S.assert_has_sup_4s(&madhvac, Pum, &["maDU/ce"]); + s.assert_has_sup_2p(&madhvac, Pum, &["maDU/caH"]); + s.assert_has_sup_3s(&madhvac, Pum, &["maDU/cA"]); + s.assert_has_sup_4s(&madhvac, Pum, &["maDU/ce"]); } diff --git a/vidyut-prakriya/tests/integration/kashika_6_2.rs b/vidyut-prakriya/tests/integration/kashika_6_2.rs index da5659a..8c42b91 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_2.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_2.rs @@ -1,48 +1,57 @@ extern crate test_utils; -use lazy_static::lazy_static; +use std::sync::OnceLock; + use test_utils::*; -lazy_static! { - static ref S: Tester = Tester::with_svara_rules(); +static S: OnceLock = OnceLock::new(); + +fn get_tester() -> &'static Tester { + S.get_or_init(|| Tester::with_svara_rules()) } #[test] fn sutra_6_2_27() { - S.assert_has_karmadharaya("kumAra", "pratyenas", &["ku/mArapratyenas"]); + let s = get_tester(); + s.assert_has_karmadharaya("kumAra", "pratyenas", &["ku/mArapratyenas"]); } #[ignore] #[test] fn sutra_6_2_179() { - S.assert_has_bahuvrihi("antar", "vana", &["antarvaRa/"]); + let s = get_tester(); + s.assert_has_bahuvrihi("antar", "vana", &["antarvaRa/"]); } #[ignore] #[test] fn sutra_6_2_180() { - S.assert_has_bahuvrihi("pra", "antar", &["prAnta/r"]); + let s = get_tester(); + s.assert_has_bahuvrihi("pra", "antar", &["prAnta/r"]); } #[test] fn sutra_6_2_185() { - S.assert_has_bahuvrihi("aBi", "muKa", &["aBimuKa/"]); + let s = get_tester(); + s.assert_has_bahuvrihi("aBi", "muKa", &["aBimuKa/"]); } #[test] fn sutra_6_2_186() { - S.assert_has_bahuvrihi("apa", "muKa", &["apamuKa/"]); + let s = get_tester(); + s.assert_has_bahuvrihi("apa", "muKa", &["apamuKa/"]); } #[test] fn sutra_6_2_187() { - S.assert_has_bahuvrihi("apa", "sPiga", &["apasPiga/"]); - S.assert_has_bahuvrihi("apa", "pUta", &["apapUta/"]); - S.assert_has_bahuvrihi("apa", "vIRA", &["apavIRA/"]); - S.assert_has_bahuvrihi("apa", "aYjas", &["apAYja/s"]); - S.assert_has_bahuvrihi("apa", "aDvan", &["apADva/n"]); - S.assert_has_bahuvrihi("apa", "kukzi", &["apakukzi/"]); - S.assert_has_bahuvrihi("apa", "sIra", &["apasIra/"]); - S.assert_has_bahuvrihi("apa", "nAman", &["apanAma/n"]); + let s = get_tester(); + s.assert_has_bahuvrihi("apa", "sPiga", &["apasPiga/"]); + s.assert_has_bahuvrihi("apa", "pUta", &["apapUta/"]); + s.assert_has_bahuvrihi("apa", "vIRA", &["apavIRA/"]); + s.assert_has_bahuvrihi("apa", "aYjas", &["apAYja/s"]); + s.assert_has_bahuvrihi("apa", "aDvan", &["apADva/n"]); + s.assert_has_bahuvrihi("apa", "kukzi", &["apakukzi/"]); + s.assert_has_bahuvrihi("apa", "sIra", &["apasIra/"]); + s.assert_has_bahuvrihi("apa", "nAman", &["apanAma/n"]); // TODO: apahala, etc. } diff --git a/vidyut-sandhi/Cargo.toml b/vidyut-sandhi/Cargo.toml index 5580984..28d763b 100644 --- a/vidyut-sandhi/Cargo.toml +++ b/vidyut-sandhi/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" clap = { version = "4.0.12", features = ["derive"] } compact_str = "0.7.1" csv = "1.1.6" -lazy_static = "1.4.0" rustc-hash = "2.1.0" [dev-dependencies] diff --git a/vidyut-sandhi/src/generator.rs b/vidyut-sandhi/src/generator.rs index e88f31e..2eecc08 100644 --- a/vidyut-sandhi/src/generator.rs +++ b/vidyut-sandhi/src/generator.rs @@ -3,8 +3,9 @@ Utilities for generating sandhi rules. For details, see the `create_rules` function below. */ +use std::sync::OnceLock; + use crate::sounds::Set; -use lazy_static::lazy_static; /// All vowels. const AC: &str = "aAiIuUfFxXeEoO"; @@ -63,18 +64,16 @@ fn is_savarna_ac(f: char, s: char) -> bool { /// Returns whether the given sound is voiced. fn is_ghoshavat(c: char) -> bool { - lazy_static! { - static ref S: Set = Set::from(r"aAiIuUfFxXeEoOgGNjJYqQRdDnbBmyrlvh"); - } - S.contains(c) + static S: OnceLock = OnceLock::new(); + S.get_or_init(|| Set::from(r"aAiIuUfFxXeEoOgGNjJYqQRdDnbBmyrlvh")); + S.get().unwrap().contains(c) } /// Returns whether the given sound is nasal. fn is_anunasika(c: char) -> bool { - lazy_static! { - static ref S: Set = Set::from(r"NYRnm"); - } - S.contains(c) + static S: OnceLock = OnceLock::new(); + S.get_or_init(|| Set::from(r"NYRnm")); + S.get().unwrap().contains(c) } /// Returns the lengthened form of a vowel. diff --git a/vidyut-sandhi/src/sounds.rs b/vidyut-sandhi/src/sounds.rs index 1a92159..3ad1bdd 100644 --- a/vidyut-sandhi/src/sounds.rs +++ b/vidyut-sandhi/src/sounds.rs @@ -1,6 +1,6 @@ //! Utility functions for checking Sanskrit sounds. -use lazy_static::lazy_static; +use std::sync::OnceLock; /// A set of Sanskrit sounds. /// @@ -43,10 +43,9 @@ impl Default for Set { /// - other punctuation characters (|, ||, numbers) /// - characters or symbols from non-SLP1 encodings pub fn is_sanskrit(c: char) -> bool { - lazy_static! { - static ref CHARS: Set = Set::from("aAiIuUfFxXeEoOMHkKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL'"); - } - CHARS.contains(c) + static CHARS: OnceLock = OnceLock::new(); + CHARS.get_or_init(|| Set::from("aAiIuUfFxXeEoOMHkKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL'")); + CHARS.get().unwrap().contains(c) } /// Returns whether the given sound is a vowel. @@ -54,19 +53,17 @@ pub fn is_sanskrit(c: char) -> bool { /// `ac` is the Paninian name for the Sanskrit vowels. #[allow(dead_code)] pub fn is_ac(c: char) -> bool { - lazy_static! { - static ref AC: Set = Set::from("aAiIuUfFxXeEoO"); - } - AC.contains(c) + static AC: OnceLock = OnceLock::new(); + AC.get_or_init(|| Set::from("aAiIuUfFxXeEoO")); + AC.get().unwrap().contains(c) } /// Returns whether the given sound is voiced. #[allow(dead_code)] pub fn is_ghosha(c: char) -> bool { - lazy_static! { - static ref GHOSHA: Set = Set::from("aAiIuUfFxXeEoOgGNjJYqQRdDnbBmyrlvh"); - } - GHOSHA.contains(c) + static GHOSHA: OnceLock = OnceLock::new(); + GHOSHA.get_or_init(|| Set::from("aAiIuUfFxXeEoOgGNjJYqQRdDnbBmyrlvh")); + GHOSHA.get().unwrap().contains(c) } #[cfg(test)] diff --git a/vidyut-sandhi/src/splitter.rs b/vidyut-sandhi/src/splitter.rs index 72a3d7c..d6b260d 100644 --- a/vidyut-sandhi/src/splitter.rs +++ b/vidyut-sandhi/src/splitter.rs @@ -17,11 +17,11 @@ use crate::errors::Result; use crate::sounds; use crate::sounds::Set; use compact_str::CompactString; -use lazy_static::lazy_static; use rustc_hash::FxHashMap; use std::cmp; use std::collections::hash_map::Keys; use std::path::Path; +use std::sync::OnceLock; /// Describes the type of sandhi split that occurred. #[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] @@ -331,42 +331,60 @@ fn visarga_to_r(s: &str) -> CompactString { } /// Returns whether the first item in a sandhi split is OK according to some basic heuristics. +#[allow(dead_code)] fn is_good_first(text: &str) -> bool { - lazy_static! { - static ref AC: Set = Set::from("aAiIuUfFxXeEoO"); - static ref SPARSHA: Set = Set::from("kKgGNcCjJYwWqQRtTdDnpPbBm"); - static ref HAL: Set = Set::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvzSsh"); - // Vowels, standard consonants, and "s" and "r" - static ref VALID_FINALS: Set = Set::from("aAiIuUfFxXeEoOHkNwRtpnmsr"); - } + static AC: OnceLock = OnceLock::new(); + AC.get_or_init(|| Set::from("aAiIuUfFxXeEoO")); + let ac = AC.get().unwrap(); + + // static SPARSHA: OnceLock = OnceLock::new(); + // SPARSHA.get_or_init(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBm")); + // let sparsha = SPARSHA.get().unwrap(); + + static HAL: OnceLock = OnceLock::new(); + HAL.get_or_init(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvzSsh")); + let hal = HAL.get().unwrap(); + + // Vowels, standard consonants, and "s" and "r" + static VALID_FINALS: OnceLock = OnceLock::new(); + VALID_FINALS.get_or_init(|| Set::from("aAiIuUfFxXeEoOHkNwRtpnmsr")); + let valid_finals = VALID_FINALS.get().unwrap(); + let mut chars = text.chars().rev(); if let (Some(y), Some(x)) = (chars.next(), chars.next()) { - if (AC.contains(x) && AC.contains(y)) || (HAL.contains(x) && HAL.contains(y)) { + if (ac.contains(x) && ac.contains(y)) || (hal.contains(x) && hal.contains(y)) { return false; } } match text.chars().last() { - Some(c) => VALID_FINALS.contains(c), + Some(c) => valid_finals.contains(c), None => true, } } /// Returns whether the second item in a sandhi split is OK according to some basic heuristics. fn is_good_second(text: &str) -> bool { - lazy_static! { - static ref YAN: Set = Set::from("yrlv"); - static ref AC: Set = Set::from("aAiIuUfFxXeEoO"); - static ref SPARSHA: Set = Set::from("kKgGNcCjJYwWqQRtTdDnpPbBm"); - } + static YAN: OnceLock = OnceLock::new(); + YAN.get_or_init(|| Set::from("yrlv")); + let yan = YAN.get().unwrap(); + + static AC: OnceLock = OnceLock::new(); + AC.get_or_init(|| Set::from("aAiIuUfFxXeEoO")); + let ac = AC.get().unwrap(); + + static SPARSHA: OnceLock = OnceLock::new(); + SPARSHA.get_or_init(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBm")); + let sparsha = SPARSHA.get().unwrap(); + let mut chars = text.chars(); if let (Some(x), Some(y)) = (chars.next(), chars.next()) { - if AC.contains(x) && AC.contains(y) { + if ac.contains(x) && ac.contains(y) { // Must not start with a double vowel. // But, "afRin" is acceptable. text.starts_with("afR") } else { // Initial yrlv must not be followed by sparsha. - !(YAN.contains(x) && SPARSHA.contains(y)) + !(yan.contains(x) && sparsha.contains(y)) } } else { true