Skip to main content

rapiddoc_core/
resources.rs

1//! Resource policy shared by the production pipeline and low-level diagnostics.
2//!
3//! Python-compatible document calls do not impose invented document-size or
4//! cumulative-work cutoffs. Explicit diagnostic limits and arithmetic/shape
5//! validation remain separate. The scope is thread-local and restored on unwind.
6use std::{cell::Cell, marker::PhantomData, rc::Rc};
7
8thread_local! { static COMPATIBLE: Cell<bool> = const { Cell::new(false) }; }
9
10pub struct Scope {
11    previous: bool,
12    _thread: PhantomData<Rc<()>>,
13}
14
15pub fn python_compatible() -> Scope {
16    Scope {
17        previous: COMPATIBLE.with(|v| v.replace(true)),
18        _thread: PhantomData,
19    }
20}
21
22#[inline]
23pub fn is_python_compatible() -> bool {
24    COMPATIBLE.with(Cell::get)
25}
26
27impl Drop for Scope {
28    fn drop(&mut self) {
29        COMPATIBLE.with(|v| v.set(self.previous));
30    }
31}
32
33pub trait Bound: Copy + Default + PartialEq {
34    const REPRESENTABLE_MAX: Self;
35}
36macro_rules! bounds {
37    ($($t:ty),*) => {$ (impl Bound for $t { const REPRESENTABLE_MAX: Self = <$t>::MAX; })*};
38}
39bounds!(usize, u32, u64, i32, i64, f32, f64);
40
41/// Apply an artificial diagnostic cap only outside production document calls.
42/// This never replaces checked arithmetic, valid tensor shapes, or model rules.
43#[inline]
44pub fn limit<T: Bound>(diagnostic: T) -> T {
45    if COMPATIBLE.with(Cell::get) && diagnostic != T::default() {
46        T::REPRESENTABLE_MAX
47    } else {
48        diagnostic
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55
56    #[test]
57    fn compatible_scope_restores_nested_panicking_and_other_thread_calls() {
58        assert_eq!(limit(256_000_000usize), 256_000_000);
59        {
60            let _outer = python_compatible();
61            assert_eq!(limit(256_000_000usize), usize::MAX);
62            assert_eq!(limit(0usize), 0); // A zero capacity never becomes an allocation request.
63            {
64                let _inner = python_compatible();
65            }
66            assert_eq!(limit(1000usize), usize::MAX);
67            assert_eq!(
68                std::thread::spawn(|| limit(1000usize)).join().unwrap(),
69                1000
70            );
71        }
72        let _ = std::panic::catch_unwind(|| {
73            let _scope = python_compatible();
74            panic!("deliberate scope unwind");
75        });
76        assert_eq!(limit(1000usize), 1000);
77    }
78}