use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize, Default, Clone, PartialEq)]
#[serde(untagged)]
pub enum StringOrList {
#[default]
Empty,
String(String),
List(Vec<String>),
}
impl StringOrList {
#[must_use]
pub fn map_each<T, F>(&self, f: F) -> Vec<T>
where
F: Fn(&str) -> T,
{
match self {
Self::Empty => Vec::new(),
Self::String(s) => vec![f(s)],
Self::List(v) => {
let mut mapped = Vec::with_capacity(v.len());
let mut index = 0;
while let Some(value) = v.get(index) {
mapped.push(f(value));
index += 1;
}
mapped
}
}
}
#[must_use]
pub fn to_string_vec(&self) -> Vec<String> {
self.map_each(str::to_owned)
}
#[must_use]
pub fn as_single(&self) -> Option<&str> {
match self {
Self::String(s) => Some(s),
Self::List(v) if v.len() == 1 => v.first().map(String::as_str),
_ => None,
}
}
#[must_use]
pub const fn is_empty_content(&self) -> bool {
match self {
Self::Empty => true,
Self::String(_) => false,
Self::List(v) => v.is_empty(),
}
}
}
impl From<&str> for StringOrList {
fn from(value: &str) -> Self {
Self::String(value.to_owned())
}
}
impl From<String> for StringOrList {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl From<Vec<String>> for StringOrList {
fn from(value: Vec<String>) -> Self {
Self::List(value)
}
}