use std::collections::HashMap;
use std::hash::{BuildHasher, RandomState};
use crate::{Format, ParData, Parameter, Transformer};
#[derive(Debug, Default)]
pub struct TransformerBuilder<
#[cfg(not(feature = "serde"))] S = RandomState,
#[cfg(feature = "serde")] S: Default = RandomState,
> {
format: Option<Format>,
parameter: HashMap<u32, Parameter, S>,
}
impl TransformerBuilder<RandomState> {
#[inline]
pub fn new() -> Self {
Self::with_hasher(RandomState::new())
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
format: None,
parameter: HashMap::with_capacity_and_hasher(capacity, RandomState::new()),
}
}
}
impl<#[cfg(not(feature = "serde"))] S, #[cfg(feature = "serde")] S: Default> TransformerBuilder<S> {
#[inline]
pub fn with_hasher(hash_builder: S) -> Self {
Self {
format: None,
parameter: HashMap::with_hasher(hash_builder),
}
}
#[inline]
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
Self {
format: None,
parameter: HashMap::with_capacity_and_hasher(capacity, hash_builder),
}
}
#[inline]
pub const fn format(mut self, format: Format) -> Self {
self.format = Some(format);
self
}
#[inline]
#[must_use]
pub fn build(self) -> Transformer<ParData<S>> {
let data = ParData::new(
self.format.expect("mesh_unit is not assigned"),
self.parameter,
);
Transformer::new(data)
}
}
impl<#[cfg(not(feature = "serde"))] S, #[cfg(feature = "serde")] S: Default> TransformerBuilder<S>
where
S: BuildHasher,
{
#[inline]
pub fn parameter(mut self, meshcode: u32, parameter: impl Into<Parameter>) -> Self {
self.parameter.insert(meshcode, parameter.into());
self
}
#[inline]
pub fn parameters(
mut self,
parameters: impl IntoIterator<Item = (u32, impl Into<Parameter>)>,
) -> Self {
for (meshcode, parameter) in parameters.into_iter() {
self.parameter.insert(meshcode, parameter.into());
}
self
}
#[inline]
pub fn shrink_to_fit(mut self) -> Self {
self.parameter.shrink_to_fit();
self
}
}
impl<#[cfg(not(feature = "serde"))] S, #[cfg(feature = "serde")] S: Default> Clone
for TransformerBuilder<S>
where
S: Clone,
{
#[inline]
fn clone(&self) -> Self {
Self {
format: self.format,
parameter: self.parameter.clone(),
}
}
#[inline]
fn clone_from(&mut self, source: &Self) {
self.format.clone_from(&source.format);
self.parameter.clone_from(&source.parameter);
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
#[should_panic(expected = "mesh_unit is not assigned")]
fn test_panic() {
let _ = TransformerBuilder::new().build();
}
#[test]
fn test_impl() {
let tf = TransformerBuilder::new()
.format(Format::SemiDynaEXE)
.parameter(54401005, (-0.00622, 0.01516, 0.0946))
.parameter(54401055, [-0.0062, 0.01529, 0.08972])
.parameter(54401100, Parameter::new(-0.00663, 0.01492, 0.10374))
.build();
assert_eq!(
tf.get(&54401005),
Some(&Parameter::new(-0.00622, 0.01516, 0.0946))
);
assert_eq!(
tf.get(&54401055),
Some(&Parameter::new(-0.0062, 0.01529, 0.08972))
);
assert_eq!(
tf.get(&54401100),
Some(&Parameter::new(-0.00663, 0.01492, 0.10374))
);
}
}