pub trait HashMapLike< K, E >
where
K : core::cmp::Eq + core::hash::Hash,
{
fn insert( &mut self, k : K, e : E ) -> Option< E >;
}
impl< K, E > HashMapLike< K, E > for std::collections::HashMap< K, E >
where
K : core::cmp::Eq + core::hash::Hash,
{
fn insert( &mut self, k : K, e : E ) -> Option< E >
{
std::collections::HashMap::insert( self, k, e )
}
}
#[derive( Debug, Default )]
pub struct HashMapFormer< K, E, HashMap, Former, ContainerEnd >
where
K : core::cmp::Eq + core::hash::Hash,
HashMap : HashMapLike< K, E > + std::default::Default,
ContainerEnd : Fn( &mut Former, core::option::Option< HashMap > ),
{
container : Option< HashMap >,
former : Former,
on_end : ContainerEnd,
_e_phantom : core::marker::PhantomData< E >,
_k_phantom : core::marker::PhantomData< K >,
}
impl< K, E, HashMap, Former, ContainerEnd >
HashMapFormer< K, E, HashMap, Former, ContainerEnd >
where
K : core::cmp::Eq + core::hash::Hash,
HashMap : HashMapLike< K, E > + std::default::Default,
ContainerEnd : Fn( &mut Former, core::option::Option< HashMap > ),
{
pub fn new( former : Former, container : core::option::Option< HashMap >, on_end : ContainerEnd ) -> Self
{
Self
{
former,
container,
on_end,
_e_phantom : core::marker::PhantomData,
_k_phantom : core::marker::PhantomData,
}
}
pub fn replace( mut self, container : HashMap ) -> Self
{
debug_assert!( self.container.is_none() );
self.container = Some( container );
self
}
pub fn end( mut self ) -> Former
{
let container = self.container.take();
( self.on_end )( &mut self.former, container );
self.former
}
pub fn insert< K2, E2 >( mut self, k : K2, e : E2 ) -> Self
where
K2 : core::convert::Into< K >,
E2 : core::convert::Into< E >,
{
if self.container.is_none()
{
self.container = core::option::Option::Some( Default::default() );
}
if let core::option::Option::Some( ref mut container ) = self.container
{
container.insert( k.into(), e.into() );
}
self
}
}