|
1 | 1 | #![deny(clippy::all)] |
2 | 2 |
|
| 3 | +use std::path::Path; |
| 4 | + |
| 5 | +use napi::Error; |
3 | 6 | use napi_derive::napi; |
| 7 | +use rstack_ignore::{IgnoreMatcher as CoreIgnoreMatcher, IgnoreSource as CoreIgnoreSource}; |
| 8 | + |
| 9 | +/// A Gitignore-compatible pattern source received from JavaScript. |
| 10 | +#[napi(object, object_to_js = false)] |
| 11 | +pub struct IgnoreSource { |
| 12 | + /// Directory that patterns are resolved from. |
| 13 | + pub root_path: String, |
| 14 | + /// Newline-delimited Gitignore patterns. |
| 15 | + pub patterns: String, |
| 16 | +} |
4 | 17 |
|
| 18 | +/// JavaScript-facing wrapper around the compiled Rust matcher. |
5 | 19 | #[napi] |
6 | | -pub fn native_ping(input: String) -> String { |
7 | | - format!("pong:{input}") |
| 20 | +pub struct IgnoreMatcher { |
| 21 | + inner: CoreIgnoreMatcher, |
8 | 22 | } |
9 | 23 |
|
10 | | -#[cfg(test)] |
11 | | -mod tests { |
12 | | - use super::native_ping; |
| 24 | +#[napi] |
| 25 | +impl IgnoreMatcher { |
| 26 | + /// Compiles all pattern sources once and keeps the result for repeated path checks. |
| 27 | + #[napi(constructor)] |
| 28 | + pub fn new(sources: Vec<IgnoreSource>) -> napi::Result<Self> { |
| 29 | + let sources = sources |
| 30 | + .into_iter() |
| 31 | + .map(|source| CoreIgnoreSource::new(source.root_path, source.patterns)); |
| 32 | + let inner = CoreIgnoreMatcher::new(sources).map_err(|error| { |
| 33 | + Error::from_reason(format!("Failed to compile ignore patterns: {error}")) |
| 34 | + })?; |
| 35 | + |
| 36 | + Ok(Self { inner }) |
| 37 | + } |
13 | 38 |
|
14 | | - #[test] |
15 | | - fn formats_ping_response() { |
16 | | - assert_eq!(native_ping("rstack".to_string()), "pong:rstack"); |
| 39 | + /// Returns whether a file or directory is ignored by any source. |
| 40 | + #[napi] |
| 41 | + pub fn is_ignored(&mut self, file_path: String, is_directory: bool) -> bool { |
| 42 | + self.inner.is_ignored(Path::new(&file_path), is_directory) |
17 | 43 | } |
18 | 44 | } |
0 commit comments