bon_macros/collections/
mod.rs

1pub(crate) mod map;
2pub(crate) mod set;
3
4use crate::util::prelude::*;
5use std::collections::HashSet;
6
7pub(crate) fn validate_expressions_are_unique<'k, I>(err_label: &str, items: I) -> Option<Error>
8where
9    I: IntoIterator<Item = &'k syn::Expr>,
10{
11    let mut errors = Error::accumulator();
12
13    let mut exprs = HashSet::new();
14
15    items
16        .into_iter()
17        .filter(|item| is_pure(item))
18        .for_each(|new_item| {
19            let existing = match exprs.replace(new_item) {
20                Some(existing) => existing,
21                _ => return,
22            };
23            errors.extend([
24                err!(existing, "duplicate {err_label}"),
25                err!(new_item, "duplicate {err_label}"),
26            ]);
27        });
28
29    errors.finish().err()
30}
31
32fn is_pure(expr: &syn::Expr) -> bool {
33    match expr {
34        syn::Expr::Binary(binary) => is_pure(&binary.left) && is_pure(&binary.right),
35        syn::Expr::Group(group) => is_pure(&group.expr),
36        syn::Expr::Lit(_) => true,
37        syn::Expr::Paren(paren) => is_pure(&paren.expr),
38        syn::Expr::Unary(unary) => is_pure(&unary.expr),
39        _ => false,
40    }
41}