Skip to main content

pcap_processor/commands/
unique.rs

1use crate::cli::{SortOrder, UniqueArgs};
2use crate::error::Result;
3use crate::output::{OutputData, ValueEntry, format_output};
4use crate::tshark::{TsharkConfig, TsharkRunner, TsharkValidator};
5use std::collections::HashMap;
6
7pub fn run_unique(args: UniqueArgs, tshark_path: Option<std::path::PathBuf>) -> Result<()> {
8    let config = TsharkConfig::detect(tshark_path)?;
9    let runner = TsharkRunner::new(config);
10    let mut validator = TsharkValidator::new(&runner);
11
12    // Validate field
13    validator.validate_field(&args.field)?;
14
15    // Validate filter if provided
16    if let Some(ref filter) = args.filter {
17        validator.validate_filter(filter)?;
18    }
19
20    // Expand file patterns
21    let files = validator.expand_files(&args.files)?;
22
23    // Collect all values from all files
24    let mut value_counts: HashMap<String, usize> = HashMap::new();
25
26    for file in &files {
27        let values = runner.extract_field_values(
28            file,
29            &args.field,
30            args.filter.as_deref(),
31            args.no_resolve,
32        )?;
33
34        for value in values {
35            *value_counts.entry(value).or_insert(0) += 1;
36        }
37    }
38
39    // Convert to entries
40    let mut entries: Vec<ValueEntry> = value_counts
41        .into_iter()
42        .map(|(value, count)| ValueEntry { value, count })
43        .collect();
44
45    // Sort
46    match args.sort {
47        SortOrder::Value => {
48            entries.sort_by(|a, b| a.value.cmp(&b.value));
49        }
50        SortOrder::Count => {
51            entries.sort_by(|a, b| b.count.cmp(&a.count).then(a.value.cmp(&b.value)));
52        }
53    }
54
55    // Build output data
56    let data = OutputData {
57        field: args.field,
58        total_unique: entries.len(),
59        values: entries,
60    };
61
62    // Format and print output
63    let output = format_output(&data, args.format, args.count)?;
64    print!("{}", output);
65
66    Ok(())
67}