diff options
| author | u <@> | 2026-03-10 18:10:22 +0200 |
|---|---|---|
| committer | u <@> | 2026-03-10 18:48:28 +0200 |
| commit | bfc2cabc3b0d6af8c7ca0496b7bd815fdbb658f6 (patch) | |
| tree | 5a44e556b7a868116bb926fb32ccf5e8b7e17199 | |
| parent | a30fb6fc7ef30bd2173282872c58b3e57ed63609 (diff) | |
lol i dont care
| -rw-r--r-- | src/lib.rs | 6 | ||||
| -rw-r--r-- | src/solar.rs | 91 |
2 files changed, 57 insertions, 40 deletions
@@ -1,6 +1,10 @@ +#![feature(negative_impls)] +#![feature(freeze)] +#![feature(freeze_impls)] +#![allow(internal_features)] #![allow(mutable_transmutes)] use maud::{html, Markup, PreEscaped, DOCTYPE}; -use regex::{Regex, Match}; +use regex::{Match, Regex}; use std::mem::{take, transmute}; use worker::*; diff --git a/src/solar.rs b/src/solar.rs index 3cf0c95..4bff33a 100644 --- a/src/solar.rs +++ b/src/solar.rs @@ -6,7 +6,8 @@ // based on https://prospertimes.neocities.org/solarterms.js use num::cast; use std::{ - mem::MaybeUninit, + marker::Freeze, + mem::{transmute, MaybeUninit}, ops::{Div, Rem}, sync::LazyLock, }; @@ -191,50 +192,63 @@ where align(6 * g - 5 * z, 60, 0) } +struct Cell<T: ?Sized> { + val: T, +} +impl<T: ?Sized> Cell<T> { + pub fn get(&self) -> &mut T { + unsafe { transmute(&self.val) } + } +} +unsafe impl<T: ?Sized + Send> Sync for Cell<T> {} +// technically i dont need this because wasm mutable globals are enabled, +// and Freeze is only needed for targets with a separate .rodata +// i dont really care either way but this is how UnsafeCell does it +// lang = "unsafe_cell" (apparently an extremely integral part of rust) +// does additional stuff but this is sufficient for the compiler to not +// put it on .rodata for normal targets +impl<T: ?Sized> !Freeze for Cell<T> {} + fn stday(i: usize, y: usize) -> f64 { const YEARS: usize = 200; + const ARRLEN: usize = YEARS * TERMS.len(); + static STDAYS: Cell<[f64; ARRLEN]> = Cell { + val: [0.; ARRLEN], + }; // rust doesnt have (*a)[n], | @ least ill have2 use a cr8 4 it // also lazy_static doesnt work with mutables (im not using mutex) - static mut STDAYS: Vec<f64> = vec![]; - static mut INIT: bool = false; - assert!((UNIT_YR..YEARS + UNIT_YR).contains(&y)); - unsafe { - if !INIT { - STDAYS = vec![0.; YEARS * TERMS.len()]; - INIT = true; - } - let idx = y - UNIT_YR; - let ret = &mut STDAYS[idx * TERMS.len() + i]; - (if int(*ret) != 0 { - *ret - } else { - let d = compute_solarterm_day(i, y); - *ret = d; - d - }) - .floor() - } + assert!((UNIT_YR..UNIT_YR + YEARS).contains(&y)); + let idx = y - UNIT_YR; + let ret = &mut STDAYS.get()[idx * TERMS.len() + i]; + (if int(*ret) != 0 { + *ret + } else { + let d = compute_solarterm_day(i, y); + *ret = d; + d + }) + .floor() } -static GANZHIS: LazyLock<Vec<String>> = LazyLock::new(|| { - const gan: [char; 10] = - ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']; - const zhi: [char; 12] = [ - '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥', - ]; - let mut tmp: Vec<String> = Vec::with_capacity(60); - (0..60).for_each(|i| { - // looks so much worse than using format!() - // cant be bothered to benchmark - let mut s = gan[i % 10].to_string(); - s.push(zhi[i % 12]); - tmp.push(s); - }); - tmp -}); - #[must_use] pub fn ganzhi(i: usize) -> &'static str { + static GANZHIS: LazyLock<Vec<String>> = LazyLock::new(|| { + const gan: [char; 10] = + ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸']; + const zhi: [char; 12] = [ + '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', + '亥', + ]; + let mut tmp: Vec<String> = Vec::with_capacity(60); + (0..60).for_each(|i| { + // looks so much worse than using format!() + // cant be bothered to benchmark + let mut s = gan[i % 10].to_string(); + s.push(zhi[i % 12]); + tmp.push(s); + }); + tmp + }); &GANZHIS[i] } @@ -243,10 +257,9 @@ const fn int(x: f64) -> usize { x as usize // x.as_int_unchecked() // wont work on wasm } -static JIAZI: LazyLock<usize> = LazyLock::new(|| int(JD!(UNIT_YR, 1, 31))); - #[must_use] pub fn solar(y: usize, m: usize, d: usize) -> SexagenaryDate { + static JIAZI: LazyLock<usize> = LazyLock::new(|| int(JD!(UNIT_YR, 1, 31))); let jdf = JD!(y, m, d); let jd = int(jdf); let a = compute_ang(jdf); |
