use snafu::OptionExt; use std::{collections::HashMap, slice::SliceIndex}; use util_error::{IndexOfFailed, KeyNotFound, OutOfBounds, UtilResult}; pub mod util_error; // replace HashMap method that returns Option with one that returns Result and proper Error pub fn map_get<'a, K: ::std::fmt::Debug + std::hash::Hash + std::cmp::Eq, V>( hash_map: &'a HashMap, key: &K, ) -> UtilResult<&'a V> { let value = hash_map.get(key).context(KeyNotFound { key_str: format!("{:?}", key), })?; Ok(value) } pub fn index_of(elt: T, slice: &[T]) -> UtilResult { let index = slice .iter() .position(|slice_elt| *slice_elt == elt) .with_context(|| { let elt_str = format!("{:?}", elt); let collection_str = format!("{:?}", slice); IndexOfFailed { elt_str, collection_str, } })?; Ok(index) } // replaces slice method that return Option with one that return Result and proper Error pub fn slice_get(index: usize, slice: &[T]) -> UtilResult<&>::Output> { let elt_ref = slice.get(index).context(OutOfBounds { index, collection_name: "Slice", len: slice.len(), })?; Ok(elt_ref) } pub fn slice_get_mut( index: usize, slice: &mut [T], ) -> UtilResult<&mut >::Output> { let slice_len = slice.len(); let elt_ref = slice.get_mut(index).context(OutOfBounds { index, collection_name: "Slice", len: slice_len, })?; Ok(elt_ref) } // returns the index of the first occurrence of element and index of the last occurrence pub fn first_last_index_of( elt: T, slice: &[T], ) -> UtilResult<(usize, usize)> { let mut first_index_opt = None; let mut last_index_opt = None; for (index, list_elt) in slice.iter().enumerate() { if *list_elt == elt { if first_index_opt.is_none() { first_index_opt = Some(index); last_index_opt = Some(index); } else { last_index_opt = Some(index) } } else if last_index_opt.is_some() { break; } } if let (Some(first_index), Some(last_index)) = (first_index_opt, last_index_opt) { Ok((first_index, last_index)) } else { let elt_str = format!("{:?}", elt); let collection_str = format!("{:?}", slice); IndexOfFailed { elt_str, collection_str, } .fail() } }