|
20 | 20 | //! println!("{}", json); |
21 | 21 | //! ``` |
22 | 22 | //! |
23 | | -//! # Safety |
| 23 | +//! # Thread Safety |
24 | 24 | //! |
25 | | -//! This crate uses FFI to call into GNU Bash's C code. The parser |
26 | | -//! uses global state, so parsing is not thread-safe. All parsing |
27 | | -//! should be done from a single thread. |
| 25 | +//! **Important:** This crate is NOT thread-safe. The underlying bash parser |
| 26 | +//! uses global state that cannot be safely accessed from multiple threads. |
| 27 | +//! |
| 28 | +//! - Call [`init()`] once from your main thread before parsing |
| 29 | +//! - Perform all parsing operations from a single thread |
| 30 | +//! - For tests, set `RUST_TEST_THREADS=1` or use `cargo test -- --test-threads=1` |
| 31 | +//! |
| 32 | +//! The [`init()`] function uses `std::sync::Once` internally, making it safe |
| 33 | +//! to call multiple times (subsequent calls are no-ops). |
28 | 34 | //! |
29 | 35 | //! # License |
30 | 36 | //! |
@@ -75,18 +81,71 @@ pub enum ParseError { |
75 | 81 | /// This must be called once before any parsing operations. |
76 | 82 | /// It is safe to call multiple times - subsequent calls are no-ops. |
77 | 83 | /// |
| 84 | +/// # Thread Safety |
| 85 | +/// |
| 86 | +/// While this function is safe to call from multiple threads (it uses |
| 87 | +/// `std::sync::Once` internally), the actual parsing operations are |
| 88 | +/// NOT thread-safe. Call this from your main thread, then ensure all |
| 89 | +/// parsing happens on a single thread. |
| 90 | +/// |
78 | 91 | /// # Example |
79 | 92 | /// |
80 | 93 | /// ```no_run |
81 | 94 | /// use bash_ast::init; |
82 | 95 | /// |
83 | 96 | /// init(); |
84 | | -/// // Now you can parse scripts |
| 97 | +/// // Now you can parse scripts (from a single thread) |
85 | 98 | /// ``` |
86 | 99 | pub fn init() { |
87 | 100 | bash_init::init(); |
88 | 101 | } |
89 | 102 |
|
| 103 | +/// Test utilities for bash-ast |
| 104 | +/// |
| 105 | +/// This module provides helper functions for writing tests that use bash-ast. |
| 106 | +/// These utilities handle initialization and provide better error messages. |
| 107 | +/// |
| 108 | +/// # Example |
| 109 | +/// |
| 110 | +/// ```no_run |
| 111 | +/// use bash_ast::test_utils; |
| 112 | +/// |
| 113 | +/// #[test] |
| 114 | +/// fn my_test() { |
| 115 | +/// test_utils::setup(); |
| 116 | +/// // Your test code here |
| 117 | +/// } |
| 118 | +/// ``` |
| 119 | +pub mod test_utils { |
| 120 | + use super::init; |
| 121 | + |
| 122 | + /// Initialize bash for testing |
| 123 | + /// |
| 124 | + /// This is a convenience function for tests that calls [`init()`]. |
| 125 | + /// It's safe to call multiple times. |
| 126 | + /// |
| 127 | + /// **Important:** Tests using bash-ast must run single-threaded. |
| 128 | + /// Configure this via: |
| 129 | + /// - `.cargo/config.toml`: `RUST_TEST_THREADS = "1"` |
| 130 | + /// - Command line: `cargo test -- --test-threads=1` |
| 131 | + /// |
| 132 | + /// # Example |
| 133 | + /// |
| 134 | + /// ```no_run |
| 135 | + /// use bash_ast::test_utils; |
| 136 | + /// |
| 137 | + /// #[test] |
| 138 | + /// fn test_parsing() { |
| 139 | + /// test_utils::setup(); |
| 140 | + /// let result = bash_ast::parse("echo hello"); |
| 141 | + /// assert!(result.is_ok()); |
| 142 | + /// } |
| 143 | + /// ``` |
| 144 | + pub fn setup() { |
| 145 | + init(); |
| 146 | + } |
| 147 | +} |
| 148 | + |
90 | 149 | /// Parse a bash script and return the AST |
91 | 150 | /// |
92 | 151 | /// # Arguments |
|
0 commit comments