rubydex 0.1.0.beta11 → 0.1.0.beta13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +23 -23
  3. data/README.md +125 -125
  4. data/THIRD_PARTY_LICENSES.html +2018 -945
  5. data/exe/rdx +47 -47
  6. data/ext/rubydex/declaration.c +453 -388
  7. data/ext/rubydex/declaration.h +23 -23
  8. data/ext/rubydex/definition.c +284 -197
  9. data/ext/rubydex/definition.h +28 -28
  10. data/ext/rubydex/diagnostic.c +6 -6
  11. data/ext/rubydex/diagnostic.h +11 -11
  12. data/ext/rubydex/document.c +97 -98
  13. data/ext/rubydex/document.h +10 -10
  14. data/ext/rubydex/extconf.rb +146 -127
  15. data/ext/rubydex/graph.c +701 -512
  16. data/ext/rubydex/graph.h +10 -10
  17. data/ext/rubydex/handle.h +44 -44
  18. data/ext/rubydex/location.c +22 -22
  19. data/ext/rubydex/location.h +15 -15
  20. data/ext/rubydex/reference.c +123 -104
  21. data/ext/rubydex/reference.h +15 -16
  22. data/ext/rubydex/rubydex.c +22 -22
  23. data/ext/rubydex/utils.c +108 -86
  24. data/ext/rubydex/utils.h +34 -28
  25. data/lib/rubydex/comment.rb +17 -17
  26. data/lib/rubydex/declaration.rb +11 -0
  27. data/lib/rubydex/diagnostic.rb +21 -21
  28. data/lib/rubydex/failures.rb +15 -15
  29. data/lib/rubydex/graph.rb +98 -92
  30. data/lib/rubydex/keyword.rb +17 -0
  31. data/lib/rubydex/keyword_parameter.rb +13 -0
  32. data/lib/rubydex/location.rb +90 -90
  33. data/lib/rubydex/mixin.rb +22 -0
  34. data/lib/rubydex/version.rb +5 -5
  35. data/lib/rubydex.rb +24 -20
  36. data/rbi/rubydex.rbi +425 -310
  37. data/rust/Cargo.lock +1851 -1851
  38. data/rust/Cargo.toml +29 -29
  39. data/rust/about.toml +10 -10
  40. data/rust/{about.hbs → about_templates/about.hbs} +81 -78
  41. data/rust/about_templates/mingw_licenses.hbs +1071 -0
  42. data/rust/rubydex/Cargo.toml +42 -42
  43. data/rust/rubydex/src/compile_assertions.rs +13 -13
  44. data/rust/rubydex/src/diagnostic.rs +110 -109
  45. data/rust/rubydex/src/errors.rs +28 -28
  46. data/rust/rubydex/src/indexing/local_graph.rs +224 -224
  47. data/rust/rubydex/src/indexing/rbs_indexer.rs +1551 -1554
  48. data/rust/rubydex/src/indexing/ruby_indexer.rs +2329 -6753
  49. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +4962 -0
  50. data/rust/rubydex/src/indexing.rs +210 -210
  51. data/rust/rubydex/src/integrity.rs +279 -278
  52. data/rust/rubydex/src/job_queue.rs +199 -205
  53. data/rust/rubydex/src/lib.rs +17 -17
  54. data/rust/rubydex/src/listing.rs +371 -272
  55. data/rust/rubydex/src/main.rs +160 -160
  56. data/rust/rubydex/src/model/built_in.rs +83 -0
  57. data/rust/rubydex/src/model/comment.rs +24 -24
  58. data/rust/rubydex/src/model/declaration.rs +679 -588
  59. data/rust/rubydex/src/model/definitions.rs +1682 -1602
  60. data/rust/rubydex/src/model/document.rs +222 -252
  61. data/rust/rubydex/src/model/encoding.rs +22 -22
  62. data/rust/rubydex/src/model/graph.rs +3782 -3556
  63. data/rust/rubydex/src/model/id.rs +110 -110
  64. data/rust/rubydex/src/model/identity_maps.rs +58 -58
  65. data/rust/rubydex/src/model/ids.rs +60 -38
  66. data/rust/rubydex/src/model/keywords.rs +256 -256
  67. data/rust/rubydex/src/model/name.rs +298 -298
  68. data/rust/rubydex/src/model/references.rs +111 -111
  69. data/rust/rubydex/src/model/string_ref.rs +50 -50
  70. data/rust/rubydex/src/model/visibility.rs +41 -41
  71. data/rust/rubydex/src/model.rs +15 -14
  72. data/rust/rubydex/src/offset.rs +147 -147
  73. data/rust/rubydex/src/position.rs +6 -6
  74. data/rust/rubydex/src/query.rs +1841 -1700
  75. data/rust/rubydex/src/resolution.rs +1852 -5895
  76. data/rust/rubydex/src/resolution_tests.rs +4701 -0
  77. data/rust/rubydex/src/stats/memory.rs +71 -71
  78. data/rust/rubydex/src/stats/orphan_report.rs +264 -263
  79. data/rust/rubydex/src/stats/timer.rs +127 -127
  80. data/rust/rubydex/src/stats.rs +11 -11
  81. data/rust/rubydex/src/test_utils/context.rs +226 -226
  82. data/rust/rubydex/src/test_utils/graph_test.rs +730 -679
  83. data/rust/rubydex/src/test_utils/local_graph_test.rs +602 -602
  84. data/rust/rubydex/src/test_utils.rs +52 -52
  85. data/rust/rubydex/src/visualization/dot.rs +192 -176
  86. data/rust/rubydex/src/visualization.rs +6 -6
  87. data/rust/rubydex/tests/cli.rs +185 -167
  88. data/rust/rubydex-mcp/Cargo.toml +28 -28
  89. data/rust/rubydex-mcp/src/main.rs +48 -48
  90. data/rust/rubydex-mcp/src/server.rs +1145 -1145
  91. data/rust/rubydex-mcp/src/tools.rs +49 -49
  92. data/rust/rubydex-mcp/tests/mcp.rs +302 -302
  93. data/rust/rubydex-sys/Cargo.toml +20 -20
  94. data/rust/rubydex-sys/build.rs +14 -14
  95. data/rust/rubydex-sys/cbindgen.toml +12 -12
  96. data/rust/rubydex-sys/src/declaration_api.rs +485 -469
  97. data/rust/rubydex-sys/src/definition_api.rs +443 -352
  98. data/rust/rubydex-sys/src/diagnostic_api.rs +99 -99
  99. data/rust/rubydex-sys/src/document_api.rs +85 -54
  100. data/rust/rubydex-sys/src/graph_api.rs +1017 -700
  101. data/rust/rubydex-sys/src/lib.rs +79 -9
  102. data/rust/rubydex-sys/src/location_api.rs +79 -79
  103. data/rust/rubydex-sys/src/name_api.rs +187 -135
  104. data/rust/rubydex-sys/src/reference_api.rs +267 -195
  105. data/rust/rubydex-sys/src/utils.rs +70 -70
  106. data/rust/rustfmt.toml +2 -2
  107. metadata +16 -9
  108. data/lib/rubydex/librubydex_sys.so +0 -0
@@ -1,205 +1,199 @@
1
- use std::panic::{self, AssertUnwindSafe};
2
- use std::{
3
- sync::Arc,
4
- sync::atomic::{AtomicUsize, Ordering},
5
- thread,
6
- };
7
-
8
- use crossbeam_deque::{Injector, Steal, Stealer, Worker};
9
- use crossbeam_utils::Backoff;
10
-
11
- /// Work-stealing queue that balances jobs across worker threads.
12
- ///
13
- /// Jobs are pushed onto the global `injector`, then workers move them into their
14
- /// own local queues. Work stealing lets idle workers drain the global injector
15
- /// first and then steal from peers, keeping the CPU busy without coarse locks.
16
- /// `in_flight` tracks outstanding jobs so threads can tell when all work
17
- /// (including work spawned by other jobs) has finished.
18
- #[derive(Default)]
19
- pub struct JobQueue {
20
- /// Global queue feeding newly discovered jobs to workers.
21
- injector: Injector<Box<dyn Job + Send + 'static>>,
22
- /// Count of jobs that have been queued but not yet completed.
23
- in_flight: AtomicUsize,
24
- }
25
-
26
- impl JobQueue {
27
- #[must_use]
28
- pub fn new() -> Self {
29
- Self {
30
- injector: Injector::new(),
31
- in_flight: AtomicUsize::new(0),
32
- }
33
- }
34
-
35
- /// Enqueue a job for processing.
36
- pub fn push(&self, job: Box<dyn Job + Send + 'static>) {
37
- // Increment the count of in-flight jobs to indicate a new job has been enqueued.
38
- self.in_flight.fetch_add(1, Ordering::Relaxed);
39
- // Push the job onto the global injector queue for later execution by workers.
40
- self.injector.push(job);
41
- }
42
-
43
- /// Run jobs until the queue is empty.
44
- ///
45
- /// Accepts the shared queue so jobs can enqueue more work while the runner is processing.
46
- pub fn run(queue: &Arc<JobQueue>) {
47
- // Determine the number of worker threads to launch.
48
- // Use the number of available logical CPUs, falling back to 4 if detection fails.
49
- let worker_count = thread::available_parallelism()
50
- .map(std::num::NonZeroUsize::get)
51
- .unwrap_or(4);
52
-
53
- Self::run_with_workers(queue, worker_count);
54
- }
55
-
56
- /// Spin up worker threads and return their handles without waiting for completion.
57
- ///
58
- /// The caller is responsible for joining the returned handles. This allows
59
- /// overlapping other work (e.g. merging results) with job processing.
60
- pub fn run_without_waiting(queue: &Arc<JobQueue>) -> Vec<thread::JoinHandle<()>> {
61
- let worker_count = thread::available_parallelism()
62
- .map(std::num::NonZeroUsize::get)
63
- .unwrap_or(4);
64
-
65
- Self::spawn_workers(queue, worker_count)
66
- }
67
-
68
- /// Spin up `worker_count` threads, each with its own local queue, and block until all threads finish.
69
- ///
70
- /// Workers steal from each other and from the global injector to keep the work balanced.
71
- fn run_with_workers(queue: &Arc<JobQueue>, worker_count: usize) {
72
- let handles = Self::spawn_workers(queue, worker_count);
73
-
74
- // Wait for all worker threads to finish before returning.
75
- for handle in handles {
76
- handle.join().expect("Worker thread panicked");
77
- }
78
- }
79
-
80
- /// Spin up `worker_count` threads and return their join handles.
81
- fn spawn_workers(queue: &Arc<JobQueue>, worker_count: usize) -> Vec<thread::JoinHandle<()>> {
82
- let mut handles = Vec::with_capacity(worker_count);
83
- let mut workers = Vec::with_capacity(worker_count);
84
- let mut stealers = Vec::with_capacity(worker_count);
85
-
86
- for _ in 0..worker_count {
87
- let worker = Worker::new_fifo();
88
- stealers.push(worker.stealer()); // For stealing jobs from this queue
89
- workers.push(worker);
90
- }
91
-
92
- // Wrap all stealers in an Arc so they can be shared across all threads.
93
- let stealers = Arc::new(stealers);
94
-
95
- // Start a worker thread for each local queue.
96
- for worker in workers {
97
- let queue = Arc::clone(queue);
98
- let stealers = Arc::clone(&stealers);
99
- handles.push(thread::spawn(move || queue.worker_loop(&worker, &stealers)));
100
- }
101
-
102
- handles
103
- }
104
-
105
- /// Drain work for a single worker.
106
- ///
107
- /// The worker prefers its local queue, then the global injector, then other
108
- /// workers. If no job is immediately available, it backs off briefly and
109
- /// exits once `in_flight` reaches zero (meaning no pending work anywhere).
110
- fn worker_loop(
111
- &self,
112
- local: &Worker<Box<dyn Job + Send + 'static>>,
113
- stealers: &Arc<Vec<Stealer<Box<dyn Job + Send + 'static>>>>,
114
- ) {
115
- // Create a backoff utility for yielding when no job is immediately available
116
- let backoff = Backoff::new();
117
-
118
- // Loop until all work is done (in_flight reaches zero)
119
- loop {
120
- // Try to steal the next job to execute. Prioritize own local queue, then global, then peers.
121
- let Some(job) = Self::steal_job(local, stealers, &self.injector) else {
122
- if self.in_flight.load(Ordering::Acquire) == 0 {
123
- // All work is done, exit the worker loop
124
- break;
125
- }
126
- // No work found and still pending jobs: brief pause before retrying
127
- backoff.snooze();
128
- continue;
129
- };
130
-
131
- // Reset backoff as we've obtained a job to process
132
- backoff.reset();
133
-
134
- // Run the job and capture any panics so we can propagate them safely
135
- let result = panic::catch_unwind(AssertUnwindSafe(|| job.run()));
136
-
137
- // Job completed; decrement the in-flight job counter
138
- self.in_flight.fetch_sub(1, Ordering::Relaxed);
139
-
140
- // If the job panicked, resume the panic on this thread
141
- if let Err(payload) = result {
142
- panic::resume_unwind(payload);
143
- }
144
- }
145
- }
146
-
147
- /// Find the next job for a worker.
148
- ///
149
- /// Priority: pop from the worker's local queue, steal a batch from the
150
- /// global injector, then try stealing from peer workers. Returning `None`
151
- /// signals the caller to back off or eventually exit if no jobs remain.
152
- fn steal_job(
153
- local: &Worker<Box<dyn Job + Send + 'static>>,
154
- stealers: &[Stealer<Box<dyn Job + Send + 'static>>],
155
- injector: &Injector<Box<dyn Job + Send + 'static>>,
156
- ) -> Option<Box<dyn Job + Send + 'static>> {
157
- // First, try to pop a job from the worker's own local queue (fastest, lowest contention).
158
- if let Some(job) = local.pop() {
159
- return Some(job);
160
- }
161
-
162
- // If the local queue is empty, try to steal a batch of jobs from the global injector queue.
163
- match injector.steal_batch_and_pop(local) {
164
- Steal::Success(job) => return Some(job), // Successfully stole a job from the global injector.
165
- Steal::Retry => return None, // Transient failure; signal to caller to back off and try again later.
166
- Steal::Empty => {} // No jobs available in the global injector; continue to peers.
167
- }
168
-
169
- // As a last resort, attempt to steal jobs from each of the peer workers' queues.
170
- for stealer in stealers {
171
- match stealer.steal_batch_and_pop(local) {
172
- Steal::Success(job) => return Some(job), // Successfully stole a job from a peer.
173
- Steal::Retry => return None, // Retry advised; caller should back off and loop.
174
- Steal::Empty => {} // No jobs in this peer; try next peer.
175
- }
176
- }
177
-
178
- // No jobs available from any source.
179
- None
180
- }
181
- }
182
-
183
- /// Unit of work scheduled on a `JobQueue`.
184
- ///
185
- /// # Example
186
- ///
187
- /// ```
188
- /// use std::sync::Arc;
189
- /// use rubydex::job_queue::{Job, JobQueue};
190
- ///
191
- /// struct PrintJob;
192
- ///
193
- /// impl Job for PrintJob {
194
- /// fn run(&self) {
195
- /// println!("hello from a worker");
196
- /// }
197
- /// }
198
- ///
199
- /// let queue = Arc::new(JobQueue::new());
200
- /// queue.push(Box::new(PrintJob));
201
- /// JobQueue::run(&queue);
202
- /// ```
203
- pub trait Job: Send {
204
- fn run(&self);
205
- }
1
+ use std::panic::{self, AssertUnwindSafe};
2
+ use std::{
3
+ sync::Arc,
4
+ sync::atomic::{AtomicUsize, Ordering},
5
+ thread,
6
+ };
7
+
8
+ use crossbeam_deque::{Injector, Steal, Stealer, Worker};
9
+ use crossbeam_utils::Backoff;
10
+
11
+ /// Work-stealing queue that balances jobs across worker threads.
12
+ ///
13
+ /// Jobs are pushed onto the global `injector`, then workers move them into their
14
+ /// own local queues. Work stealing lets idle workers drain the global injector
15
+ /// first and then steal from peers, keeping the CPU busy without coarse locks.
16
+ /// `in_flight` tracks outstanding jobs so threads can tell when all work
17
+ /// (including work spawned by other jobs) has finished.
18
+ #[derive(Default)]
19
+ pub struct JobQueue {
20
+ /// Global queue feeding newly discovered jobs to workers.
21
+ injector: Injector<Box<dyn Job + Send + 'static>>,
22
+ /// Count of jobs that have been queued but not yet completed.
23
+ in_flight: AtomicUsize,
24
+ }
25
+
26
+ impl JobQueue {
27
+ #[must_use]
28
+ pub fn new() -> Self {
29
+ Self {
30
+ injector: Injector::new(),
31
+ in_flight: AtomicUsize::new(0),
32
+ }
33
+ }
34
+
35
+ /// Enqueue a job for processing.
36
+ pub fn push(&self, job: Box<dyn Job + Send + 'static>) {
37
+ // Increment the count of in-flight jobs to indicate a new job has been enqueued.
38
+ self.in_flight.fetch_add(1, Ordering::Relaxed);
39
+ // Push the job onto the global injector queue for later execution by workers.
40
+ self.injector.push(job);
41
+ }
42
+
43
+ /// Run jobs until the queue is empty.
44
+ ///
45
+ /// Accepts the shared queue so jobs can enqueue more work while the runner is processing.
46
+ pub fn run(queue: &Arc<JobQueue>) {
47
+ // Determine the number of worker threads to launch.
48
+ // Use the number of available logical CPUs, falling back to 4 if detection fails.
49
+ let worker_count = thread::available_parallelism().map_or(4, std::num::NonZeroUsize::get);
50
+ Self::run_with_workers(queue, worker_count);
51
+ }
52
+
53
+ /// Spin up worker threads and return their handles without waiting for completion.
54
+ ///
55
+ /// The caller is responsible for joining the returned handles. This allows
56
+ /// overlapping other work (e.g. merging results) with job processing.
57
+ pub fn run_without_waiting(queue: &Arc<JobQueue>) -> Vec<thread::JoinHandle<()>> {
58
+ let worker_count = thread::available_parallelism().map_or(4, std::num::NonZeroUsize::get);
59
+ Self::spawn_workers(queue, worker_count)
60
+ }
61
+
62
+ /// Spin up `worker_count` threads, each with its own local queue, and block until all threads finish.
63
+ ///
64
+ /// Workers steal from each other and from the global injector to keep the work balanced.
65
+ fn run_with_workers(queue: &Arc<JobQueue>, worker_count: usize) {
66
+ let handles = Self::spawn_workers(queue, worker_count);
67
+
68
+ // Wait for all worker threads to finish before returning.
69
+ for handle in handles {
70
+ handle.join().expect("Worker thread panicked");
71
+ }
72
+ }
73
+
74
+ /// Spin up `worker_count` threads and return their join handles.
75
+ fn spawn_workers(queue: &Arc<JobQueue>, worker_count: usize) -> Vec<thread::JoinHandle<()>> {
76
+ let mut handles = Vec::with_capacity(worker_count);
77
+ let mut workers = Vec::with_capacity(worker_count);
78
+ let mut stealers = Vec::with_capacity(worker_count);
79
+
80
+ for _ in 0..worker_count {
81
+ let worker = Worker::new_fifo();
82
+ stealers.push(worker.stealer()); // For stealing jobs from this queue
83
+ workers.push(worker);
84
+ }
85
+
86
+ // Wrap all stealers in an Arc so they can be shared across all threads.
87
+ let stealers = Arc::new(stealers);
88
+
89
+ // Start a worker thread for each local queue.
90
+ for worker in workers {
91
+ let queue = Arc::clone(queue);
92
+ let stealers = Arc::clone(&stealers);
93
+ handles.push(thread::spawn(move || queue.worker_loop(&worker, &stealers)));
94
+ }
95
+
96
+ handles
97
+ }
98
+
99
+ /// Drain work for a single worker.
100
+ ///
101
+ /// The worker prefers its local queue, then the global injector, then other
102
+ /// workers. If no job is immediately available, it backs off briefly and
103
+ /// exits once `in_flight` reaches zero (meaning no pending work anywhere).
104
+ fn worker_loop(
105
+ &self,
106
+ local: &Worker<Box<dyn Job + Send + 'static>>,
107
+ stealers: &Arc<Vec<Stealer<Box<dyn Job + Send + 'static>>>>,
108
+ ) {
109
+ // Create a backoff utility for yielding when no job is immediately available
110
+ let backoff = Backoff::new();
111
+
112
+ // Loop until all work is done (in_flight reaches zero)
113
+ loop {
114
+ // Try to steal the next job to execute. Prioritize own local queue, then global, then peers.
115
+ let Some(job) = Self::steal_job(local, stealers, &self.injector) else {
116
+ if self.in_flight.load(Ordering::Acquire) == 0 {
117
+ // All work is done, exit the worker loop
118
+ break;
119
+ }
120
+ // No work found and still pending jobs: brief pause before retrying
121
+ backoff.snooze();
122
+ continue;
123
+ };
124
+
125
+ // Reset backoff as we've obtained a job to process
126
+ backoff.reset();
127
+
128
+ // Run the job and capture any panics so we can propagate them safely
129
+ let result = panic::catch_unwind(AssertUnwindSafe(|| job.run()));
130
+
131
+ // Job completed; decrement the in-flight job counter
132
+ self.in_flight.fetch_sub(1, Ordering::Relaxed);
133
+
134
+ // If the job panicked, resume the panic on this thread
135
+ if let Err(payload) = result {
136
+ panic::resume_unwind(payload);
137
+ }
138
+ }
139
+ }
140
+
141
+ /// Find the next job for a worker.
142
+ ///
143
+ /// Priority: pop from the worker's local queue, steal a batch from the
144
+ /// global injector, then try stealing from peer workers. Returning `None`
145
+ /// signals the caller to back off or eventually exit if no jobs remain.
146
+ fn steal_job(
147
+ local: &Worker<Box<dyn Job + Send + 'static>>,
148
+ stealers: &[Stealer<Box<dyn Job + Send + 'static>>],
149
+ injector: &Injector<Box<dyn Job + Send + 'static>>,
150
+ ) -> Option<Box<dyn Job + Send + 'static>> {
151
+ // First, try to pop a job from the worker's own local queue (fastest, lowest contention).
152
+ if let Some(job) = local.pop() {
153
+ return Some(job);
154
+ }
155
+
156
+ // If the local queue is empty, try to steal a batch of jobs from the global injector queue.
157
+ match injector.steal_batch_and_pop(local) {
158
+ Steal::Success(job) => return Some(job), // Successfully stole a job from the global injector.
159
+ Steal::Retry => return None, // Transient failure; signal to caller to back off and try again later.
160
+ Steal::Empty => {} // No jobs available in the global injector; continue to peers.
161
+ }
162
+
163
+ // As a last resort, attempt to steal jobs from each of the peer workers' queues.
164
+ for stealer in stealers {
165
+ match stealer.steal_batch_and_pop(local) {
166
+ Steal::Success(job) => return Some(job), // Successfully stole a job from a peer.
167
+ Steal::Retry => return None, // Retry advised; caller should back off and loop.
168
+ Steal::Empty => {} // No jobs in this peer; try next peer.
169
+ }
170
+ }
171
+
172
+ // No jobs available from any source.
173
+ None
174
+ }
175
+ }
176
+
177
+ /// Unit of work scheduled on a `JobQueue`.
178
+ ///
179
+ /// # Example
180
+ ///
181
+ /// ```
182
+ /// use std::sync::Arc;
183
+ /// use rubydex::job_queue::{Job, JobQueue};
184
+ ///
185
+ /// struct PrintJob;
186
+ ///
187
+ /// impl Job for PrintJob {
188
+ /// fn run(&self) {
189
+ /// println!("hello from a worker");
190
+ /// }
191
+ /// }
192
+ ///
193
+ /// let queue = Arc::new(JobQueue::new());
194
+ /// queue.push(Box::new(PrintJob));
195
+ /// JobQueue::run(&queue);
196
+ /// ```
197
+ pub trait Job: Send {
198
+ fn run(&self);
199
+ }
@@ -1,17 +1,17 @@
1
- pub mod compile_assertions;
2
- pub mod diagnostic;
3
- pub mod errors;
4
- pub mod indexing;
5
- pub mod integrity;
6
- pub mod job_queue;
7
- pub mod listing;
8
- pub mod model;
9
- pub mod offset;
10
- pub mod position;
11
- pub mod query;
12
- pub mod resolution;
13
- pub mod stats;
14
- pub mod visualization;
15
-
16
- #[cfg(any(test, feature = "test_utils"))]
17
- pub mod test_utils;
1
+ pub mod compile_assertions;
2
+ pub mod diagnostic;
3
+ pub mod errors;
4
+ pub mod indexing;
5
+ pub mod integrity;
6
+ pub mod job_queue;
7
+ pub mod listing;
8
+ pub mod model;
9
+ pub mod offset;
10
+ pub mod position;
11
+ pub mod query;
12
+ pub mod resolution;
13
+ pub mod stats;
14
+ pub mod visualization;
15
+
16
+ #[cfg(any(test, feature = "test_utils"))]
17
+ pub mod test_utils;