use std ::collections ::{ HashMap, BTreeMap };
use crate ::TemplateValue;
#[ derive( Debug, Clone ) ]
#[ cfg_attr( any( feature = "json", feature = "yaml" ), derive( serde::Serialize, serde::Deserialize ) )]
pub struct Values< V = crate ::Value >
where
V: TemplateValue
{
inner: HashMap< String, Option< V > >,
}
impl< V > Values< V >
where
V: TemplateValue
{
#[must_use]
pub fn new() -> Self
{
Self
{
inner: HashMap ::new(),
}
}
pub fn insert( &mut self, key: &str, value: V )
{
self.inner.insert( key.to_string(), Some( value ) );
}
pub fn insert_if_empty( &mut self, key: &str, value: V )
{
let should_insert = match self.inner.get( key )
{
None | Some( None ) => true, Some( Some( _ ) ) => false, };
if should_insert
{
self.inner.insert( key.to_string(), Some( value ) );
}
}
pub fn insert_none( &mut self, key: &str )
{
self.inner.insert( key.to_string(), None );
}
#[must_use]
pub fn get( &self, key: &str ) -> Option< &V >
{
self.inner.get( key ).and_then( | opt | opt.as_ref() )
}
#[must_use]
pub fn has_value( &self, key: &str ) -> bool
{
self.inner.get( key ).and_then( | opt | opt.as_ref() ).is_some()
}
#[must_use]
pub fn needs_prompt( &self, key: &str ) -> bool
{
matches!( self.inner.get( key ), Some( None ) )
}
#[must_use]
pub fn len( &self ) -> usize
{
self.inner.len()
}
#[must_use]
pub fn is_empty( &self ) -> bool
{
self.inner.is_empty()
}
#[must_use]
pub fn to_serializable( &self ) -> BTreeMap< String, serde_json ::Value >
where
V: serde ::Serialize
{
self
.inner
.iter()
.map( | ( key, value ) |
{
let json_value = match value
{
Some( v ) => serde_json ::to_value( v ).unwrap_or( serde_json ::Value ::Null ),
None => serde_json ::Value ::String( "___UNSPECIFIED___".to_string() ),
};
( key.clone(), json_value )
})
.collect()
}
}
impl< V > Default for Values< V >
where
V: TemplateValue
{
fn default() -> Self
{
Self ::new()
}
}