syn-canon 0.4.0

Canonical form of a syn file, equal across formatting drift and local binder names
Documentation

syn-canon

CI crates.io docs.rs

Canonical forms of syn files. Formatting, supported style folds and local binder names share one comparison key.

use std::collections::HashSet;

let canonical = |src: &str| syn_canon::canonicalize(syn::parse_str(src).unwrap());

let mut forms = HashSet::new();
assert!(forms.insert(canonical("fn f(x: u32) -> u32 { return (x + 1); }")));
assert!(!forms.insert(canonical("fn g(y: u32) -> u32 { y + 1 }")));
assert!(forms.insert(canonical("fn f(x: u64) -> u64 { x + 1 }")));
println!("{forms:?}");

no_std with alloc. It powers cargo-echoes, which finds duplicated doctests.

Equal forms mean approximate duplication, since the normalization cannot see what the compiler resolves, such as inferred types, macro expansions or an enclosing cfg.

Stability

CanonicalForm keys and hashes are comparable within one major version. New folds require a major version.