Skip to content

Commit 906c077

Browse files
committed
Improve resolver
1 parent b9162fd commit 906c077

20 files changed

Lines changed: 1087 additions & 368 deletions

.mise.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
[tools]
2+
act = "latest"
23
rust = "1.75"

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [0.2.0] - 2025-11-26
9+
10+
### Added
11+
12+
- `TypeGroups` struct for controlling automatic type resolution (primitives, prelude, common std types)
13+
- Expanded list of Rust std types that can be automatically resolved
14+
15+
### Changed
16+
17+
- Set Rust edition to 2021
18+
- Set MSRV to 1.75
19+
20+
## [0.1.0] - Initial Release
21+
22+
Initial release of desynt library.

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "desynt"
33
description = "Convert syn paths & idents to normalised names"
44
repository = "https://github.com/jayvdb/desynt"
55
license = "MIT OR Apache-2.0"
6-
version = "0.1.0"
6+
version = "0.2.0"
77
edition = "2021"
88
rust-version = "1.75"
99

README.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,61 @@ A Rust library for handling syn objects with raw identifier prefixes and path no
1111
`desynt` provides utilities for working with [`syn`](https://github.com/dtolnay/syn) objects, particularly focusing on:
1212

1313
- **Stripping raw identifier prefixes** (`r#`) from `Ident`, `Path`, and `PathSegment` objects
14-
- **Path normalization** and canonical type resolution
15-
- **Type mapping** from various path representations to canonical forms
14+
- **Path resolution and normalization** via `PathResolver` for canonical type mapping
15+
- **Built-in type support** for Rust primitives, prelude types, and common std types
16+
- **Multiple storage backends** - HashMap (dynamic) or phf::Map (static)
1617

1718
This library is especially useful when working with proc macros or code analysis tools where you need to normalize type references regardless of how they're written in the source code.
1819

20+
## Features
21+
22+
### Raw Identifier Stripping
23+
24+
Use the `StripRaw` trait to remove `r#` prefixes from syn objects:
25+
26+
```rust
27+
use syn::Ident;
28+
use desynt::StripRaw;
29+
30+
let ident: Ident = syn::parse_str("r#type").unwrap();
31+
let stripped = ident.strip_raw();
32+
assert_eq!(stripped.to_string(), "type");
33+
```
34+
35+
### Path Resolution
36+
37+
Use `PathResolver` to normalize type paths and resolve them to canonical forms. This is particularly useful in proc macros where types can be referenced in multiple ways:
38+
39+
```rust
40+
use desynt::{TypeGroups, DynamicPathResolver};
41+
use std::collections::HashMap;
42+
use syn::Path;
43+
44+
let mut mappings = HashMap::new();
45+
mappings.insert("my_crate::types::UserId".to_string(), "UserId".to_string());
46+
47+
let resolver = DynamicPathResolver::from_map(mappings, TypeGroups::ALL);
48+
49+
// Resolves custom types
50+
let path: Path = syn::parse_str("my_crate::types::UserId").unwrap();
51+
assert_eq!(resolver.resolve(&path), Some("UserId"));
52+
53+
// Also handles type groups with various path forms
54+
let path: Path = syn::parse_str("std::option::Option").unwrap();
55+
assert_eq!(resolver.resolve(&path), Some("Option"));
56+
57+
let path: Path = syn::parse_str("Option<String>").unwrap();
58+
assert_eq!(resolver.resolve(&path), Some("Option"));
59+
```
60+
61+
### Type Group Categories
62+
63+
The `TypeGroups` struct lets you control which standard types are automatically resolved:
64+
65+
- **Primitives**: Language primitives (i8, u32, f64, bool, char, str, etc.)
66+
- **Prelude**: Types in the Rust prelude (String, Vec, Option, Result, Box)
67+
- **Common std**: Frequently used std types (HashMap, HashSet)
68+
1969
## License
2070

2171
This project is licensed under either of

examples/const_example.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use desynt::{
2-
DynamicPathResolver, EmptyStorage, PRIMITIVE_RESOLVER, PathResolver, create_static_resolver,
2+
DynamicPathResolver, EmptyStorage, PRIMITIVE_RESOLVER, PathResolver, TypeGroups,
3+
create_static_resolver,
34
};
45
use phf::{Map, phf_map};
56

@@ -42,9 +43,9 @@ const EMPTY_RESOLVER: PathResolver<EmptyStorage> = PathResolver::empty();
4243

4344
// Static resolver with custom mappings - truly const!
4445
const FULL_STATIC_RESOLVER: PathResolver<&'static Map<&'static str, &'static str>> =
45-
create_static_resolver(&CUSTOM_MAPPINGS, true);
46+
create_static_resolver(&CUSTOM_MAPPINGS, TypeGroups::ALL);
4647
const CUSTOM_ONLY_RESOLVER: PathResolver<&'static Map<&'static str, &'static str>> =
47-
create_static_resolver(&CUSTOM_MAPPINGS, false);
48+
create_static_resolver(&CUSTOM_MAPPINGS, TypeGroups::NONE);
4849

4950
fn main() {
5051
println!("=== Unified PathResolver Examples ===\n");
@@ -141,7 +142,7 @@ fn test_dynamic_resolver() {
141142
}
142143

143144
// Test modification
144-
resolver.set_use_primitives(false);
145+
resolver.set_groups(TypeGroups::NONE);
145146
println!(" After disabling primitives:");
146147
let primitive_path: syn::Path = syn::parse_str("std::primitive::i32").unwrap();
147148
match resolver.resolve(&primitive_path) {

examples/domain_specific.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use desynt::{DynamicPathResolver, PathResolver, create_static_resolver};
1+
use desynt::{DynamicPathResolver, PathResolver, TypeGroups, create_static_resolver};
22
use phf::{Map, phf_map};
33

44
// Domain-specific type mappings for web applications
@@ -62,10 +62,10 @@ const DATABASE_MAPPINGS: Map<&'static str, &'static str> = phf_map! {
6262

6363
// Create const resolvers for different domains
6464
const WEB_RESOLVER: PathResolver<&'static Map<&'static str, &'static str>> =
65-
create_static_resolver(&WEB_MAPPINGS, true);
65+
create_static_resolver(&WEB_MAPPINGS, TypeGroups::ALL);
6666

6767
const DATABASE_RESOLVER: PathResolver<&'static Map<&'static str, &'static str>> =
68-
create_static_resolver(&DATABASE_MAPPINGS, true);
68+
create_static_resolver(&DATABASE_MAPPINGS, TypeGroups::ALL);
6969

7070
fn main() {
7171
println!("=== Domain-Specific PathResolver Examples ===\n");

examples/generic_demo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fn main() {
55
println!("=== Generic Type Resolution Demo ===");
66
println!();
77

8-
let resolver = DynamicPathResolver::with_primitives();
8+
let resolver = DynamicPathResolver::with_prelude();
99

1010
// Test cases that should now work automatically
1111
let test_cases = vec![

0 commit comments

Comments
 (0)