Skip to content
Open
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
11 changes: 11 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,16 @@ jobs:
run: cargo check
- name: Cargo Test
run: cargo test
- name: Cargo Clippy
run: cargo clippy -- -D warnings
- name: Cargo format
run: cargo fmt --check
- name: Verify generated filter parser
run: |
cargo install lalrpop --version 0.23.1
lalrpop src/filter_parser.lalrpop
git diff --exit-code src/filter_parser.rs || {
echo "::error::src/filter_parser.rs does not match regenerated output from src/filter_parser.lalrpop"
echo "Run 'lalrpop src/filter_parser.lalrpop' and commit the result."
exit 1
}
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# CHANGELOG

## 0.4

### Breaking Changes
- Refactor `PatchOperation` into a tagged enum (`Add`, `Remove`, `Replace`) with `OperationTarget` variants (`WithPath`, `WithoutPath`), replacing the old `PatchOperations` struct. Paths are now parsed as `PatchPath` filter expressions instead of raw strings.
- Parameterize ID types on `User`, `Group`, `Member`, `Resource`, and `ListResponse` (default type parameter is `String`, so unparameterized usage is unchanged)
- `Member.type` changed from `Option<String>` to `Option<MemberType>` enum
- Remove `TryFrom<&str>` impls on `User` and `Group`; use `serde_json::from_str` directly
- Remove `Default` impls on `Group`, `ListResponse`, and `PatchOp`

### Added
- SCIM filter expression parser (`filter` module, RFC 7644 §3.4.2.2); `SearchRequest` and `ListQuery` now include an optional `filter` field
- Case-insensitive deserialization of `PatchOperation` ops and `MemberType` for Entra compatibility
- Lenient `bool` deserialization (accepts `"true"`/`"false"` strings) on fields like `Role.primary`

## 0.3

- Add `externalId` to user and group entities
- **Breaking** - Uses raw identifiers, converting `type_` to `r#type`
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "scim_v2"
version = "0.3.1"
version = "0.4.0"
edition = "2024"
authors = ["Dan Gericke <dan@shiftcontrol.io>"]
description = "A crate that provides utilities for working with the System for Cross-domain Identity Management (SCIM) version 2.0 protocol. (rfc7642, rfc7643, rfc7644)"
Expand All @@ -13,9 +13,14 @@ rust-version = "1.85"
[dependencies]
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.145"
lalrpop-util = { version = "0.23.1", features = ["lexer"] }
fluent-uri = "0.4.1"
thiserror = "2.0.18"

[dev-dependencies]
pretty_assertions = "1.4.1"
test-case = "3.3.1"
uuid = { version = "1.22.0", features = ["serde"]}

[lib]
doc-scrape-examples = true
Expand Down
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,25 @@ Err(e) => println !("Deserialization error: {}", e),

For more examples and usage details, refer to the documentation of each function and struct.

## Regenerating the filter parser

The SCIM filter parser (`src/filter_parser.rs`) is pre-generated from `src/filter_parser.lalrpop`
using [LALRPOP](https://github.com/lalrpop/lalrpop). The generated file is committed
to the repository so no build script is required.

If you modify `src/filter_parser.lalrpop`, regenerate `src/filter_parser.rs` by running:

```sh
cargo install lalrpop
lalrpop src/filter_parser.lalrpop
```

Commit both `src/filter_parser.lalrpop` and the updated `src/filter_parser.rs` together.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

[MIT](https://choosealicense.com/licenses/mit/)
[MIT](https://choosealicense.com/licenses/mit/)
Loading
Loading