Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,38 @@ on:
- master
- dev
- boilerplate
- idiomatic
- rc1
- rc2
- rc3
pull_request:

permissions:
contents: read

defaults:
run:
shell: bash

env:
CARGO_TERM_COLOR: always

jobs:
check:
name: Test, Clippy, Fmt, Checkers
name: Test, Clippy, Fmt, Docs, Checkers, Package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dtolnay/rust-toolchain@stable
- uses: dtolnay/rust-toolchain@master
with:
components: clippy

- name: Install nightly rustfmt
run: rustup toolchain install nightly --profile minimal --component rustfmt
toolchain: nightly-2026-08-08
components: clippy, rustfmt

- uses: Swatinem/rust-cache@v2

- name: cargo test
run: cargo test --locked
- name: cargo test (all targets)
run: cargo test --all-targets --locked

- name: cargo test (no default features)
run: cargo test --no-default-features --locked
Expand All @@ -46,7 +55,7 @@ jobs:
run: cargo test --no-default-features --features full --locked

- name: cargo clippy
run: cargo clippy --all-targets --locked -- -D warnings
run: cargo clippy --all-targets --all-features --locked -- -D warnings

- name: cargo build (examples)
run: cargo build --examples --locked
Expand All @@ -55,7 +64,7 @@ jobs:
run: cargo build --example character-play --features test-regex --locked

- name: cargo doc
run: cargo doc --no-deps --locked
run: cargo doc --no-deps --all-features --locked

- name: rustfmt
run: ./scripts/fmt --check
Expand All @@ -69,6 +78,9 @@ jobs:
- name: DERIVE_LAYOUT checker
run: python3 scripts/check_derives.py

- name: cargo publish (dry run)
run: cargo publish --dry-run --locked

msrv:
name: MSRV (1.79)
runs-on: ubuntu-latest
Expand Down
10 changes: 9 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
# shwild.Rust - CHANGES <!-- omit in toc -->
# shwild.Rust - Changes <!-- omit in toc -->


## 0.2.1 - 31st August 2026

* completed CI coverage for feature combinations, examples, documentation, Clippy, formatting, custom checkers, and package validation;
* pinned the nightly Rust toolchain used for project formatting;
* completed Cargo package metadata, docs.rs configuration, and package exclusions;
* updated **README.md** and example catalogues with current feature and source-link information;


## 0.2.0 - 10th July 2026
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 14 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,22 @@ authors = [
]
categories = [
"command-line-interface",
"parser-implementations",
"development-tools",
"parser-implementations",
"text-processing",
]
description = "Shell-compatible wildcard matching library"
documentation = "https://docs.rs/shwild"
edition = "2021"
exclude = [
".cargo",
".cursor",
".github",
".vimrc",
".vscode",
"Cargo.toml.orig",
"scripts",
"target",
".github"
]
homepage = "https://github.com/synesissoftware/shwild.Rust"
keywords = [
Expand All @@ -32,7 +38,12 @@ name = "shwild"
readme = "README.md"
repository = "https://github.com/synesissoftware/shwild.Rust"
rust-version = "1.79"
version = "0.2.0"
version = "0.2.1"

[package.metadata.docs.rs]
features = [
"full",
]


# ##########################################################
Expand Down
12 changes: 6 additions & 6 deletions EXAMPLES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# shwild.Rust Examples <!-- omit it toc -->
# shwild.Rust - Examples <!-- omit in toc -->

|Name|Source & Description|Summary|
|---|---|---|
|**list-matching-files**|[examples/list-matching-files/main.rs](/examples/list-matching-files/main.rs)<br/>[examples/list-matching-files.md](/examples/list-matching-files.md)|Lists files in the current directory whose paths match one or more shell wildcard pattern(s), using `shwild::matches()`.|
|**list-matching-files-compiled**|[examples/list-matching-files-compiled/main.rs](/examples/list-matching-files-compiled/main.rs)<br/>[examples/list-matching-files-compiled.md](/examples/list-matching-files-compiled.md)|Same as **list-matching-files**, but patterns are compiled once into `CompiledMatcher` instances before matching.|
|**character-play**|[test/scratch/character-play/main.rs](/test/scratch/character-play/main.rs)<br/>[examples/character-play.md](/examples/character-play.md)|Scratch program exercising **regex** crate Unicode matching behaviour (requires feature `"test-regex"`).|
| Name | Source & Description | Summary |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **list-matching-files** | [Source](./examples/list-matching-files/main.rs)<br/>[Description](./examples/list-matching-files.md) | Lists matching files using `shwild::matches()`. |
| **list-matching-files-compiled** | [Source](./examples/list-matching-files-compiled/main.rs)<br/>[Description](./examples/list-matching-files-compiled.md) | Lists matching files using compiled `CompiledMatcher` instances. |
| **character-play** | [Scratch source](./test/scratch/character-play/main.rs)<br/>[Description](./examples/character-play.md) | Exercises **regex** Unicode matching (requires feature `"test-regex"`). |



Expand Down
7 changes: 4 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# shwild.Rust - NEWS <!-- omit in toc -->
# shwild.Rust - News <!-- omit in toc -->

| Date | News Item |
| --------------------- | ----------------------------------------- |
| 10th July 2026 | shwild.Rust 0.2.0 released |
| 9th July 2026 | shwild.Rust 0.1.6 released |
| 31st August 2026 | [shwild.Rust 0.2.1](https://github.com/synesissoftware/shwild.Rust/releases/tag/0.2.1) released |
| 10th July 2026 | [shwild.Rust 0.2.0](https://github.com/synesissoftware/shwild.Rust/releases/tag/0.2.0) released |
| 9th July 2026 | [shwild.Rust 0.1.6](https://github.com/synesissoftware/shwild.Rust/releases/tag/0.1.6) released |
| 9th July 2026 | shwild.Rust 0.1.5 released |
| 7th July 2026 | shwild.Rust 0.1.4 released |
| 28th March 2025 | shwild.Rust 0.1.3 released |
Expand Down
95 changes: 60 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# shwild.Rust <!-- omit in toc -->

**SH**ell-compatible **WILD**cards, for **Rust** — part of the cross-language
**shwild** family.


![Language](https://img.shields.io/badge/Rust-000000?style=flat&logo=rust&logoColor=white)
[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Crates.io](https://img.shields.io/crates/v/shwild.svg)](https://crates.io/crates/shwild)
Expand All @@ -9,8 +13,6 @@
[![Last Commit](https://img.shields.io/github/last-commit/synesissoftware/shwild.Rust)](https://github.com/synesissoftware/shwild.Rust/commits/master)
[![docs.rs](https://img.shields.io/docsrs/shwild/badge.svg)](https://docs.rs/shwild)

**SH**ell-compatible **WILD**cards, for **Rust** — part of the cross-language **shwild** family.


## Table of Contents <!-- omit in toc -->

Expand All @@ -37,9 +39,12 @@

## Introduction

**shwild** is a small, standalone library, implemented in C++ with a C and a C++ API, that provides shell-compatible wildcard matching. **shwild.Rust** is a **Rust** port, with minimal API differences. The design emphasis is on simplicity-of-use, modularity, and performance.
**shwild** is a small, standalone C++ library with C and C++ APIs that
provides shell-compatible wildcard matching. **shwild.Rust** is a **Rust**
port with minimal API differences. The design emphasis is on
simplicity-of-use, modularity, and performance.

```Rust
```rust
let pattern = r"Where are the* [🐼🐻]s\?";

assert_eq!(Ok(false), shwild_matches!(pattern, ""));
Expand Down Expand Up @@ -84,20 +89,21 @@ The constant `IGNORE_CASE` causes matching to ignore case.

The `shwild::Error` enum is used to represent a parse result, defined as:

```Rust
```rust
pub enum Error {
/// Parse error encountered.
ParseError {
line : usize,
column : usize,
message : String,
line: usize,
column: usize,
message: String,
},
}
```

The `shwild::Result` enum is a specialized `std::result::Result` type for **shwild**, defined as:
The `shwild::Result` type is a specialized `std::result::Result` type for
**shwild**, defined as:

```Rust
```rust
pub type Result<T> = std_result::Result<T, shwild::Error>;
```

Expand All @@ -106,26 +112,28 @@ pub type Result<T> = std_result::Result<T, shwild::Error>;

The following crate features are defined:

| Name | Effect | Is `"default"`? | Dependent feature(s) |
| --------------------------- | ------------------------------------- | --------------- | ------------------------------------- |
| `"assertions"` | Provides `assert_shwild_matches!()` and `assert_shwild_not_matches!()` test assertion macros (via **base-traits** `AsI64`) | Yes | |
| `"lookup-ranges"` | Causes match/non-match ranges to be implemented in terms of `UnicodePointMap` (from **collect-rs** crate), resulting in significant performance improvements in parsing and matching | Yes | |
| `"null-feature"` | A feature that has no effect (and, thus, is useful for simplifying driver scripts) | **No** | |
| `"test-regex"` | Introduces a dependency to **regex** crate to support benchmark/example program(s) | **No** | |
| Name | Effect | Is `"default"`? | Dependent feature(s) |
| ----------------------- | -------------------------------------------------------------------------------- | --------------- | -------------------- |
| `"assertions"` | Provides test assertion macros; enabled by default | Yes | |
| `"flexible-flags-type"` | Allows macro flags to use types implementing `base_traits::AsI64` | **No** | **base-traits** |
| `"full"` | Enables all user-facing runtime features | **No** | |
| `"lookup-ranges"` | Uses **collect-rs** `UnicodePointMap` for more efficient range matching | Yes | **collect-rs** |
| `"null-feature"` | Has no effect; useful for simplifying driver scripts | **No** | |
| `"test-regex"` | Enables **regex** support for benchmark and scratch/example programs | **No** | **regex** |


### Functions

The `shwild::matches()` function attempts to parse a `pattern` according to `flags` and then match against it the string `input`.
The `shwild::matches()` function attempts to parse a `pattern` according to
`flags` and then match the string `input` against it.

```Rust
pub mod shwild {

pub fn matches(
pattern : &str,
input : &str,
flags : i64,
) -> Result<bool>;
```rust
pub fn matches(
pattern: &str,
input: &str,
flags: i64,
) -> Result<bool> {
// ...
}
```

Expand All @@ -134,9 +142,16 @@ pub mod shwild {

The `shwild::shwild_matches!()` macro is a shorthand for the `shwild::matches()` function, providing 2-parameter and 3-parameter forms. The 2-parameter form passes 0 for the `flags` parameter.

The `shwild::assert_shwild_matches!()` and `shwild::assert_shwild_not_matches!()` macros are test-oriented counterparts that panic on failure. Each provides 2-parameter and 3-parameter forms; the 2-parameter form passes 0 for the `flags` parameter. A parse error in the pattern panics with a descriptive message rather than returning `Err`. They are provided only when the feature `"assertions"` is enabled, which it is by default.
The `shwild::assert_shwild_matches!()` and
`shwild::assert_shwild_not_matches!()` macros are test-oriented counterparts
that panic on failure. Each provides 2-parameter and 3-parameter forms; the
2-parameter form passes 0 for the `flags` parameter. A parse error in the
pattern panics with a descriptive message rather than returning `Err`. They
are provided only when the feature `"assertions"` is enabled, which it is by
default. The optional `"flexible-flags-type"` feature also allows the
3-parameter forms to accept types implementing `base_traits::AsI64`.

```Rust
```rust
use shwild::{
assert_shwild_matches,
assert_shwild_not_matches,
Expand All @@ -153,7 +168,7 @@ The `shwild::assert_shwild_matches!()` and `shwild::assert_shwild_not_matches!()

The `shwild::CompiledMatcher` structure is the data structure that is used to parse the pattern and then test the input string. Because there is a small, but non-zero, cost to parsing patterns - and complex patterns more so, of course - so if matching is to be repeated in a context where performance costs matter then you may prefer to create an instance of `CompiledMatcher` and then use it to test against, as in:

```Rust
```rust
let pattern = r"Where are the* [🐼🐻]s\?";

let flags = 0;
Expand All @@ -170,7 +185,7 @@ The `shwild::CompiledMatcher` structure is the data structure that is used to pa

If you are ever need to get an understanding about the parsed state you can use the `Debug` implementation for the `CompiledMatcher`, as in:

```Rust
```rust

// a pattern for rudimentary Windows path names
let pattern = r"[A-Z]\?*\?*.[ce][ox][em]";
Expand Down Expand Up @@ -205,11 +220,17 @@ Defect reports, feature requests, and pull requests are welcome on https://githu

### Dependencies

**shwild.Rust** has three optional dependencies:
**shwild.Rust** has three optional runtime dependencies:

* [**base-traits**](https://github.com/synesissoftware/base-traits) - required if feature `"assertions"` is specified; supports the `flags` parameter type in `assert_shwild_matches!()` and `assert_shwild_not_matches!()` via `AsI64`;
* [**collect-rs**](https://github.com/synesissoftware/collect-rs) - required if feature `"lookup-ranges"` is specified, for more efficient range matching;
* [**regex**](https://github.com/rust-lang/regex) - required, by some benchmark/example programs only, if feature `"test-regex"` is specified;
* [**base-traits**](https://github.com/synesissoftware/base-traits) -
required if feature `"flexible-flags-type"` is specified, for
`base_traits::AsI64`;
* [**collect-rs**](https://github.com/synesissoftware/collect-rs) - required
if feature `"lookup-ranges"` is specified, for more efficient range
matching;
* [**regex**](https://github.com/rust-lang/regex) - required by some
benchmark and scratch/example programs if feature `"test-regex"` is
specified;


#### Dev Dependencies
Expand All @@ -219,19 +240,23 @@ Crates upon which **shwild** has development dependencies:
* [**criterion**](https://github.com/bheisler/criterion.rs);
* [**test_help-rs**](https://github.com/synesissoftware/test_help-rs);

The committed **Cargo.lock** is retained for reproducible development and CI
builds; locked Cargo commands are used throughout the workflow.


### Related projects

* [**shwild**](https://github.com/synesissoftware/shwild/);
* [**shwild.Go**](https://github.com/synesissoftware/shwild.Go/);
* [**base-traits**](https://github.com/synesissoftware/base-traits/);
* [**collect-rs**](https://github.com/synesissoftware/collect-rs/);
* [**shwild**](https://github.com/synesissoftware/shwild/);
* [**shwild.Go**](https://github.com/synesissoftware/shwild.Go/);


### License

**shwild** is released under the 3-clause BSD license. See [LICENSE](./LICENSE) for details.



<!-- ########################### end of file ########################### -->

Loading
Loading