use crate::core::EnvString; use std::convert::TryFrom; use std::fmt::Write; pub const COMMA: char = ','; pub const SEMI: char = ';'; pub type CommaVec<T> = SepVec<T, COMMA>; pub type SemiVec<T> = SepVec<T, SEMI>; #[derive(Debug, PartialEq, Clone)] pub struct SepVec<T, const SEP: char>(pub Vec<T>); impl<T, const SEP: char> std::ops::Deref for SepVec<T, SEP> { type Target = Vec<T>; #[inline] fn deref(&self) -> &Self::Target { &self.0 } } impl<T, const SEP: char> From<Vec<T>> for SepVec<T, SEP> { #[inline] fn from(vec: Vec<T>) -> Self { Self(vec) } } impl<T, const SEP: char> std::fmt::Display for SepVec<T, SEP> where T: std::fmt::Display, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.iter().enumerate().try_for_each(|(i, part)| { if i != 0 { f.write_char(SEP)?; } f.write_str(&part.to_string()) }) } } impl<T, const SEP: char> TryFrom<EnvString> for SepVec<T, SEP> where T: TryFrom<EnvString> + std::fmt::Display, { type Error = T::Error; fn try_from(value: EnvString) -> Result<Self, Self::Error> { let inner = value .split(SEP) .map(EnvString::from) .map(T::try_from) .collect::<Result<Vec<_>, _>>()?; Ok(Self(inner)) } }