1use std::collections::HashMap;
4
5#[non_exhaustive]
7#[derive(Clone, Debug, Eq, PartialEq)]
8pub enum BatchLabelError {
9 Empty {
11 index: usize,
13 },
14 Duplicate {
16 label: String,
18 first_index: usize,
20 duplicate_index: usize,
22 },
23}
24
25pub(crate) fn validate_labels<'a>(
26 labels: impl IntoIterator<Item = &'a str>,
27) -> Result<(), BatchLabelError> {
28 let mut seen = HashMap::new();
29 for (index, label) in labels.into_iter().enumerate() {
30 if label.is_empty() {
31 return Err(BatchLabelError::Empty { index });
32 }
33 if let Some(first_index) = seen.insert(label, index) {
34 return Err(BatchLabelError::Duplicate {
35 label: label.to_owned(),
36 first_index,
37 duplicate_index: index,
38 });
39 }
40 }
41 Ok(())
42}
43
44impl std::fmt::Display for BatchLabelError {
45 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 match self {
47 Self::Empty { index } => write!(formatter, "label at index {index} is empty"),
48 Self::Duplicate {
49 label,
50 first_index,
51 duplicate_index,
52 } => write!(
53 formatter,
54 "label {label:?} at index {duplicate_index} duplicates index {first_index}"
55 ),
56 }
57 }
58}
59
60impl std::error::Error for BatchLabelError {}