Skip to main content

provenant/utils/
spdx.rs

1use std::collections::HashSet;
2
3/// Combines multiple license expressions into a single SPDX expression.
4/// Deduplicates, sorts, and combines the expressions with " AND ".
5pub fn combine_license_expressions(
6    expressions: impl IntoIterator<Item = String>,
7) -> Option<String> {
8    let unique_expressions: HashSet<String> = expressions.into_iter().collect();
9    if unique_expressions.is_empty() {
10        return None;
11    }
12
13    let mut sorted_expressions: Vec<String> = unique_expressions.into_iter().collect();
14    sorted_expressions.sort(); // Sort for consistent output
15
16    // Join multiple expressions with AND, wrapping individual expressions in parentheses if needed
17    let combined = sorted_expressions
18        .iter()
19        .map(|expr| {
20            // If expression contains spaces and isn't already wrapped in parentheses,
21            // it might have operators, so wrap it
22            if expr.contains(' ') && !(expr.starts_with('(') && expr.ends_with(')')) {
23                format!("({})", expr)
24            } else {
25                expr.clone()
26            }
27        })
28        .collect::<Vec<_>>()
29        .join(" AND ");
30
31    Some(combined)
32}