From d1f8f439b5f4746f78ee54320490bea397dc97ac Mon Sep 17 00:00:00 2001 From: Vikram Bhaskaran Date: Sun, 19 Jan 2025 08:23:24 +1100 Subject: [PATCH] Changed LazyLock to OnceLock * Made the switch for MSRV compatibility --- vidyut-chandas/src/sounds.rs | 17 +- vidyut-cheda/src/normalize_text.rs | 10 +- vidyut-cheda/src/sounds.rs | 28 +-- vidyut-prakriya/ARCHITECTURE.md | 21 +++ vidyut-prakriya/src/angasya/abhyasasya.rs | 9 +- vidyut-prakriya/src/krt/basic.rs | 6 +- vidyut-prakriya/src/sounds.rs | 9 +- vidyut-prakriya/src/tripadi/pada_8_2.rs | 16 +- vidyut-prakriya/src/tripadi/pada_8_4.rs | 21 ++- .../tests/integration/kashika_1_1.rs | 10 +- .../tests/integration/kashika_3_1.rs | 18 +- .../tests/integration/kashika_6_1.rs | 165 ++++++++++-------- .../tests/integration/kashika_6_2.rs | 40 +++-- vidyut-sandhi/src/generator.rs | 12 +- vidyut-sandhi/src/sounds.rs | 19 +- vidyut-sandhi/src/splitter.rs | 43 +++-- 16 files changed, 271 insertions(+), 173 deletions(-) diff --git a/vidyut-chandas/src/sounds.rs b/vidyut-chandas/src/sounds.rs index fb129db..848e66b 100644 --- a/vidyut-chandas/src/sounds.rs +++ b/vidyut-chandas/src/sounds.rs @@ -1,8 +1,8 @@ -use std::sync::LazyLock; +use std::sync::OnceLock; -static HRASVA: LazyLock = LazyLock::new(|| Set::from("aiufx")); -static AC: LazyLock = LazyLock::new(|| Set::from("aAiIuUfFxXeEoO")); -static HAL: LazyLock = LazyLock::new(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvSzshL")); +static HRASVA: OnceLock = OnceLock::new(); +static AC: OnceLock = OnceLock::new(); +static HAL: OnceLock = OnceLock::new(); type Sound = char; @@ -35,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/src/normalize_text.rs b/vidyut-cheda/src/normalize_text.rs index fa96f15..9e0eccf 100644 --- a/vidyut-cheda/src/normalize_text.rs +++ b/vidyut-cheda/src/normalize_text.rs @@ -1,4 +1,4 @@ -use std::sync::LazyLock; +use std::sync::OnceLock; use regex::Regex; @@ -9,10 +9,12 @@ use regex::Regex; /// 2. Delete all whitespace spans. /// 3. Separate all remaining spans with a single " ". pub fn normalize(text: &str) -> String { - static RE: LazyLock = - LazyLock::new(|| Regex::new(r"([a-zA-Z']+)|(\s+)|([^a-zA-Z']+)").expect("always defined")); + static RE: OnceLock = OnceLock::new(); - let mut ret = RE + let re = + RE.get_or_init(|| Regex::new(r"([a-zA-Z']+)|(\s+)|([^a-zA-Z']+)").expect("always defined")); + + 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 524d4ba..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 std::sync::LazyLock; +use std::sync::OnceLock; /// A set of Sanskrit sounds. /// @@ -42,17 +42,19 @@ impl Default for SoundSet { /// - other punctuation characters (|, ||, numbers) /// - characters or symbols from non-SLP1 encodings pub fn is_sanskrit(c: char) -> bool { - static CHARS: LazyLock = - LazyLock::new(|| 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 { - static AC: LazyLock = LazyLock::new(|| 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. @@ -60,17 +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 { - static HAL: LazyLock = - LazyLock::new(|| 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 { - static GHOSHA: LazyLock = - LazyLock::new(|| 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/ARCHITECTURE.md b/vidyut-prakriya/ARCHITECTURE.md index b04c3e8..4d357b8 100644 --- a/vidyut-prakriya/ARCHITECTURE.md +++ b/vidyut-prakriya/ARCHITECTURE.md @@ -8,6 +8,7 @@ our system. This document assumes some familiarity with basic Rust concepts like structs, enums, closures, and lifetimes. + Goals and values ---------------- @@ -39,6 +40,7 @@ than wait for perfect clarity. Fortunately, we have found that as the program has grown and matured, we have become more and more able to remove hacks and solve problems in a more fundamental way. + Core data types --------------- @@ -64,18 +66,21 @@ In addition to these three types, we recommend exploring the types in the part of its API. Our hope is that callers can lean on Rust's type system to define meaningful requests and receive correct derivations. + Core modules ------------ We start our description here with the high-level `vyakarana` module then work our way into specific implementation details. + ### `vyakarana` This defines the public API. Given certain input conditions, the method here return all `Prakriya`s compatible with those conditions. `vyakarana` is a thin wrapper over the `ashtadhyayi` module, which we describe below. + ### `args` This defines the argument types that `Vyakarana` accepts. The types here follow @@ -84,6 +89,8 @@ Paninian categories as closely as possible, so we have types like `Dhatu`, arguments are well formed. For example, a `Krdanta` must have a `Dhatu` and a `Krt`. + + ### `ashtadhyayi` This defines the core rules of the Ashtadhayi. Given the input constraints @@ -111,6 +118,7 @@ their own modules. Some examples: - `unadipatha`, which defines the rules of the Unadipatha. These rules enter the Ashtadhyayi through rule 3.3.1 (*uṇādayo bahulam*) + ### `prakriya`, `terms`, and `tags` These define the `Prakriya` and `Term` types, as well as some useful secondary @@ -122,6 +130,7 @@ variety of ad-hoc flags. Since `Term` and `Tag` are not stable, we do not expose them in our public API. + ### `prakriya_stack` This module defines utilities for exploring different paths of optional rules. @@ -129,11 +138,13 @@ The core type here is `PrakriyaStack`, which manages a stack of rule paths. (`RulePathStack` might be a clearer name, but it doesn't quite roll off the tongue!) + ### `sounds` This defines various functions for testing and modifying Sanskrit sounds. The core data structure here is `Set`, which stores sounds in a simple array. + Code style ---------- @@ -154,6 +165,7 @@ the logic of each rule more obvious. Here, `p` is a `Prakriya`, `i` is the index of some `Term` within the `Prakriya`, and `|t| ...` is a closure (inline function) that accepts a `Term`. + ### Closures `run_at`, like many of the methods on `Prakriya`, accepts a closure. @@ -176,6 +188,7 @@ for `p.terms[i]`. `Prakriya` also defines many methods for working with indices, such as `find_first_where`, `find_last_where`, `find_next_where`, and so on. + ### Naming conventions Since we have so many rules to write, we use short variable names for common @@ -190,6 +203,7 @@ concepts. Some examples: [rust-borrow]: https://users.rust-lang.org/t/newbie-mut-with-nested-structs/84755 [rust-q]: https://doc.rust-lang.org/rust-by-example/std/result/question_mark.html + Control flow ------------ @@ -212,6 +226,7 @@ directly encodes a critical principle of the grammar. The sections below extend the example above and illustrate the various kinds of control flow we use, ordered from least to most complex. + ### Rule sequences The control flow in the example above is appropriate for simple sequences of @@ -226,6 +241,7 @@ if condition_2 { } ``` + ### Simple rule blocking A natural extension is to use `if`-`else` chains to enforce that only one rule @@ -241,6 +257,7 @@ if condition_1 { } ``` + ### Falling through If a rule is optional, we might wish to "fall through" and consider other @@ -260,6 +277,7 @@ if condition_2 { Here, `rule_2` is accessible even if we reject `rule_1`. + ### Simple locking If we fall through in a simple way, we could end up running both `rule_1` and @@ -282,6 +300,7 @@ if done { } ``` + ### Extended locking Sometimes, we might wish to implement rule locking over a very large section of @@ -326,6 +345,7 @@ If we use the new `do_something_1` and `do_something_2` methods here, the original `Prakriya` struct, we can access it through `lp.p`. Once the lifetime of `lp` has ended, we can continue using `p` as before. + ### Context-aware locking Suppose we wish to derive a *taddhitānta* that uses a specific @@ -333,3 +353,4 @@ taddhita-pratyaya only if available in a specific meaning context. In this case, we can extend the `LockingPrakriya` pattern above to record other useful metadata, such as the meaning condition we wish to derive (if any). For examples of this pattern, see `KrtPrakriya` and `TaddhitaPrakriya`. + diff --git a/vidyut-prakriya/src/angasya/abhyasasya.rs b/vidyut-prakriya/src/angasya/abhyasasya.rs index 664bf31..712b87a 100644 --- a/vidyut-prakriya/src/angasya/abhyasasya.rs +++ b/vidyut-prakriya/src/angasya/abhyasasya.rs @@ -6,7 +6,7 @@ abhyasasya Runs rules that modify the abhyāsa. */ -use std::sync::LazyLock; +use std::sync::OnceLock; use crate::args::Agama as A; use crate::args::Agama; @@ -34,7 +34,7 @@ const KHAY: Set = s(&["Kay"]); const F_HAL: Set = s(&["f hal"]); const PU_YAN_J: Set = s(&["pu~", "yaR", "j"]); -static KUH_CU: LazyLock = LazyLock::new(|| map("ku~ h", "cu~")); +static KUH_CU: OnceLock = OnceLock::new(); /// Simplifies the abhyasa per 7.4.60. fn try_haladi(text: &str) -> TermString { @@ -268,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 21b0d38..73dcd3f 100644 --- a/vidyut-prakriya/src/krt/basic.rs +++ b/vidyut-prakriya/src/krt/basic.rs @@ -70,13 +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 std::sync::LazyLock; +use std::sync::OnceLock; const II: Set = s(&["i"]); const UU: Set = s(&["u"]); const PU: Set = s(&["pu~"]); -static EMPTY_TERM: LazyLock = LazyLock::new(|| 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) { @@ -561,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 cbf6318..0d8b099 100644 --- a/vidyut-prakriya/src/sounds.rs +++ b/vidyut-prakriya/src/sounds.rs @@ -35,7 +35,7 @@ We chose SLP1 over something like [WX][wx] merely because we have more familiari [wx]: https://en.wikipedia.org/wiki/WX_notation */ use rustc_hash::FxHashMap; -use std::{fmt, sync::LazyLock}; +use std::{fmt, sync::OnceLock}; type Sound = char; @@ -48,7 +48,7 @@ pub const HAL: Set = s(&["hal"]); pub const YAN: Set = s(&["yaR"]); pub const VAL: Set = s(&["val"]); -static SOUND_PROPS: LazyLock> = LazyLock::new(create_sound_props); +static SOUND_PROPS: OnceLock> = OnceLock::new(); /// A set of Sanskrit sounds. /// @@ -633,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 b038442..2a561da 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_2.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_2.rs @@ -1,4 +1,4 @@ -use std::sync::LazyLock; +use std::sync::OnceLock; use crate::args::Agama as A; use crate::args::Aupadeshika as Au; @@ -26,9 +26,9 @@ const BASH: Set = s(&["baS"]); const JHAL_TO_JASH_EXCEPTIONS: Set = Set::from("cSsh"); const HASH: Set = s(&["haS"]); -static BASH_TO_BHAZ: LazyLock = LazyLock::new(|| map("baS", "Baz")); -static JHAL_TO_JASH: LazyLock = LazyLock::new(|| map("Jal", "jaS")); -static CU_TO_KU: LazyLock = LazyLock::new(|| 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| { @@ -455,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') { @@ -490,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)); } } @@ -515,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 708f317..23329aa 100644 --- a/vidyut-prakriya/src/tripadi/pada_8_4.rs +++ b/vidyut-prakriya/src/tripadi/pada_8_4.rs @@ -1,4 +1,4 @@ -use std::sync::LazyLock; +use std::sync::OnceLock; use crate::args::Aupadeshika as Au; use crate::args::Gana; @@ -28,9 +28,9 @@ const YAY: Set = s(&["yay"]); const JHAY: Set = s(&["Jay"]); const AT: Set = s(&["aw"]); -static JHAL_TO_CAR: LazyLock = LazyLock::new(|| map("Jal", "car")); -static JHAL_TO_JASH: LazyLock = LazyLock::new(|| map("Jal", "jaS")); -static JHAL_TO_JASH_CAR: LazyLock = LazyLock::new(|| 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. @@ -377,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 { @@ -392,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)); } @@ -424,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()); @@ -437,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 c2a3858..30e13c5 100644 --- a/vidyut-prakriya/tests/integration/kashika_1_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_1_1.rs @@ -1,5 +1,5 @@ extern crate test_utils; -use std::sync::LazyLock; +use std::sync::OnceLock; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; @@ -11,7 +11,7 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::Unadi; -static S: LazyLock = LazyLock::new(|| Tester::with_svara_rules()); +static S: OnceLock = OnceLock::new(); #[test] fn sutra_1_1_1() { @@ -270,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 ac8a39a..02409b6 100644 --- a/vidyut-prakriya/tests/integration/kashika_3_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_3_1.rs @@ -1,5 +1,5 @@ extern crate test_utils; -use std::sync::LazyLock; +use std::sync::OnceLock; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; @@ -10,7 +10,7 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha as TA; use vidyut_prakriya::args::*; -static S: LazyLock = LazyLock::new(|| Tester::with_svara_rules()); +static S: OnceLock = OnceLock::new(); fn sanadi(p: Pratipadika, s: Sanadi) -> Dhatu { Dhatu::nama(p, Some(s)) @@ -37,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 2b83901..773b857 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_1.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_1.rs @@ -1,5 +1,5 @@ extern crate test_utils; -use std::sync::LazyLock; +use std::sync::OnceLock; use test_utils::*; use vidyut_prakriya::args::BaseKrt as Krt; @@ -10,7 +10,11 @@ use vidyut_prakriya::args::Taddhita as T; use vidyut_prakriya::args::TaddhitaArtha::*; use vidyut_prakriya::args::*; -static S: LazyLock = LazyLock::new(|| 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_1_1() { @@ -1133,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 d6b8ad0..8c42b91 100644 --- a/vidyut-prakriya/tests/integration/kashika_6_2.rs +++ b/vidyut-prakriya/tests/integration/kashika_6_2.rs @@ -1,47 +1,57 @@ extern crate test_utils; -use std::sync::LazyLock; +use std::sync::OnceLock; use test_utils::*; -static S: LazyLock = LazyLock::new(|| 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/src/generator.rs b/vidyut-sandhi/src/generator.rs index 7c5475f..2eecc08 100644 --- a/vidyut-sandhi/src/generator.rs +++ b/vidyut-sandhi/src/generator.rs @@ -3,7 +3,7 @@ Utilities for generating sandhi rules. For details, see the `create_rules` function below. */ -use std::sync::LazyLock; +use std::sync::OnceLock; use crate::sounds::Set; @@ -64,14 +64,16 @@ fn is_savarna_ac(f: char, s: char) -> bool { /// Returns whether the given sound is voiced. fn is_ghoshavat(c: char) -> bool { - static S: LazyLock = LazyLock::new(|| 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 { - static S: LazyLock = LazyLock::new(|| 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 7ef10f9..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 std::sync::LazyLock; +use std::sync::OnceLock; /// A set of Sanskrit sounds. /// @@ -43,9 +43,9 @@ impl Default for Set { /// - other punctuation characters (|, ||, numbers) /// - characters or symbols from non-SLP1 encodings pub fn is_sanskrit(c: char) -> bool { - static CHARS: LazyLock = - LazyLock::new(|| 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. @@ -53,16 +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 { - static AC: LazyLock = LazyLock::new(|| 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 { - static GHOSHA: LazyLock = - LazyLock::new(|| 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 b3ea9a9..d6b260d 100644 --- a/vidyut-sandhi/src/splitter.rs +++ b/vidyut-sandhi/src/splitter.rs @@ -21,7 +21,7 @@ use rustc_hash::FxHashMap; use std::cmp; use std::collections::hash_map::Keys; use std::path::Path; -use std::sync::LazyLock; +use std::sync::OnceLock; /// Describes the type of sandhi split that occurred. #[derive(Copy, Clone, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)] @@ -333,39 +333,58 @@ 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 { - static AC: LazyLock = LazyLock::new(|| Set::from("aAiIuUfFxXeEoO")); - static SPARSHA: LazyLock = LazyLock::new(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBm")); - static HAL: LazyLock = LazyLock::new(|| Set::from("kKgGNcCjJYwWqQRtTdDnpPbBmyrlvzSsh")); + 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: LazyLock = LazyLock::new(|| Set::from("aAiIuUfFxXeEoOHkNwRtpnmsr")); + 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 { - static YAN: LazyLock = LazyLock::new(|| Set::from("yrlv")); - static AC: LazyLock = LazyLock::new(|| Set::from("aAiIuUfFxXeEoO")); - static SPARSHA: LazyLock = LazyLock::new(|| 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