bolero_generator/any/
default.rs1use crate::driver::object::{self, DynDriver, Object};
2use core::fmt;
3use std::cell::RefCell;
4
5pub trait Scope: 'static + DynDriver + core::any::Any {
6 fn borrowed(&mut self) -> object::Borrowed;
7}
8
9impl<T> Scope for T
10where
11 T: 'static + DynDriver + core::any::Any,
12{
13 fn borrowed(&mut self) -> object::Borrowed {
14 object::Borrowed(self)
15 }
16}
17
18type Type = Box<dyn Scope>;
19
20thread_local! {
21 static SCOPE: RefCell<Type> = RefCell::new(Box::new(Object(default())));
22}
23
24fn default() -> impl crate::Driver {
25 use rand_core::SeedableRng;
26 use rand_xoshiro::Xoshiro128PlusPlus;
27
28 let mut seed = [42; 16];
29 let _ = getrandom::fill(&mut seed);
31 let rng = Xoshiro128PlusPlus::from_seed(seed);
32 let config = crate::driver::Options::default()
34 .with_max_len(usize::MAX)
35 .with_max_depth(10);
36 crate::driver::Rng::new(rng, &config)
37}
38
39fn set(value: Type) -> Type {
40 SCOPE.with(|r| core::mem::replace(&mut *r.borrow_mut(), value))
41}
42
43struct Prev(Option<Type>);
45
46impl Prev {
47 fn reset(mut self) -> Type {
48 set(self.0.take().unwrap())
49 }
50}
51
52impl Drop for Prev {
53 fn drop(&mut self) {
54 if let Some(prev) = self.0.take() {
55 let _ = set(prev);
56 }
57 }
58}
59
60pub fn with<D, F, R>(driver: Box<D>, f: F) -> (Box<D>, R)
61where
62 D: Scope,
63 F: FnOnce() -> R,
64{
65 let prev = Prev(Some(set(driver)));
66 let res = f();
67 let driver = prev.reset();
68 let driver = if driver.type_id() == core::any::TypeId::of::<D>() {
69 unsafe {
70 let raw = Box::into_raw(driver);
71 Box::from_raw(raw as *mut D)
72 }
73 } else {
74 panic!(
75 "invalid scope state; expected {}",
76 core::any::type_name::<D>()
77 )
78 };
79 (driver, res)
80}
81
82fn borrow_with<F: FnOnce(&mut object::Borrowed) -> R, R>(f: F) -> R {
83 SCOPE.with(|r| {
84 let mut driver = r.borrow_mut();
85 let mut driver = driver.borrowed();
86 f(&mut driver)
87 })
88}
89
90#[track_caller]
91pub fn any<G: crate::ValueGenerator>(g: &G) -> G::Output {
92 borrow_with(|driver| {
93 g.generate(driver).unwrap_or_else(|| {
94 std::panic::panic_any(Error {
95 location: core::panic::Location::caller(),
96 generator: core::any::type_name::<G>(),
97 output: core::any::type_name::<G::Output>(),
98 })
99 })
100 })
101}
102
103#[track_caller]
104pub fn assume(condition: bool, message: &'static str) {
105 if !condition {
106 std::panic::panic_any(Error {
107 location: core::panic::Location::caller(),
108 generator: "<assume>",
109 output: message,
110 });
111 }
112}
113
114#[track_caller]
115pub fn fill_bytes(bytes: &mut [u8]) {
116 borrow_with(|driver| {
117 let len = bytes.len();
118 let mut hint = || (len, Some(len));
119 driver
120 .0
121 .gen_from_bytes(&mut hint, &mut |src: &[u8]| {
122 if src.len() == len {
123 bytes.copy_from_slice(src);
124 Some(len)
125 } else {
126 None
127 }
128 })
129 .unwrap_or_else(|| {
130 std::panic::panic_any(Error {
131 location: core::panic::Location::caller(),
132 generator: "<fill_bytes>",
133 output: "could not generate enough bytes",
134 });
135 })
136 })
137}
138
139#[derive(Clone)]
140pub struct Error {
141 location: &'static core::panic::Location<'static>,
142 generator: &'static str,
143 output: &'static str,
144}
145
146impl fmt::Debug for Error {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 f.debug_struct("Error")
149 .field("location", &self.location)
150 .field("generator", &self.generator)
151 .field("output", &self.output)
152 .finish()
153 }
154}
155
156impl fmt::Display for Error {
157 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
158 write!(
159 f,
160 "Could not generate value of type {} at {}",
161 self.output, self.location,
162 )
163 }
164}
165
166impl std::error::Error for Error {}