mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 06:44:46 +00:00
95 lines
2.6 KiB
Rust
95 lines
2.6 KiB
Rust
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<K, V>,
|
|
key: &K,
|
|
) -> UtilResult<&'a V> {
|
|
let value = hash_map.get(key).context(KeyNotFound {
|
|
key_str: format!("{:?}", key),
|
|
})?;
|
|
|
|
Ok(value)
|
|
}
|
|
|
|
pub fn index_of<T: ::std::fmt::Debug + std::cmp::Eq>(elt: T, slice: &[T]) -> UtilResult<usize> {
|
|
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<T>(index: usize, slice: &[T]) -> UtilResult<&<usize as SliceIndex<[T]>>::Output> {
|
|
let elt_ref = slice.get(index).context(OutOfBounds {
|
|
index,
|
|
collection_name: "Slice",
|
|
len: slice.len(),
|
|
})?;
|
|
|
|
Ok(elt_ref)
|
|
}
|
|
|
|
pub fn slice_get_mut<T>(
|
|
index: usize,
|
|
slice: &mut [T],
|
|
) -> UtilResult<&mut <usize as SliceIndex<[T]>>::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<T: ::std::fmt::Debug + std::cmp::Eq>(
|
|
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()
|
|
}
|
|
}
|