use std::{
    collections::HashMap,
    fmt::Debug,
    hash::Hash,
};

/// Bi-directional hashmap used to store the mapping between the internal
/// unstable indexes - generated by `IndexMap` and `IndexSet` - and the exposed
/// stable indexes.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct BiHashMap<Index>
where
    Index: Copy + Debug + Eq + Hash,
{
    pub(crate) left: HashMap<usize, Index>,
    pub(crate) right: HashMap<Index, usize>,
}

impl<Index> BiHashMap<Index>
where
    Index: Copy + Debug + Eq + Hash,
{
    /// Creates a new `BiHashMap` with no allocation.
    pub(crate) fn new() -> BiHashMap<Index> {
        Self {
            left: HashMap::<usize, Index>::with_capacity(0),
            right: HashMap::<Index, usize>::with_capacity(0),
        }
    }
}

impl<Index> Default for BiHashMap<Index>
where
    Index: Copy + Debug + Eq + Hash,
{
    fn default() -> Self {
        BiHashMap::new()
    }
}
