use either::{Left, Right};
use itertools::Itertools;
use std::borrow::Cow;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Value {
Scalar(String),
Array(Vec<String>),
}
use Value::*;
impl Value {
#[must_use]
pub fn scalar<S: Into<String>>(value: S) -> Self {
Scalar(value.into())
}
#[must_use]
pub fn array<I, S>(values: I) -> Self
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
Array(values.into_iter().map(Into::into).collect())
}
pub fn split(&self) -> impl Iterator<Item = &str> {
match self {
Scalar(value) => Left(value.split(':')),
Array(values) => Right(values.iter().map(String::as_str)),
}
}
pub fn quote(&self) -> QuotedValue<'_> {
QuotedValue::from(self)
}
}
impl From<String> for Value {
fn from(value: String) -> Self {
Scalar(value)
}
}
impl From<&str> for Value {
fn from(value: &str) -> Self {
Scalar(value.to_owned())
}
}
impl From<Vec<String>> for Value {
fn from(values: Vec<String>) -> Self {
Array(values)
}
}
#[derive(Clone, Copy, Debug)]
pub struct QuotedValue<'a> {
value: &'a Value,
}
impl std::fmt::Display for QuotedValue<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.value {
Scalar(value) => yash_quote::quoted(value).fmt(f),
Array(values) => write!(
f,
"({})",
values
.iter()
.format_with(" ", |value, f| f(&yash_quote::quoted(value)))
),
}
}
}
impl<'a> From<&'a Value> for QuotedValue<'a> {
fn from(value: &'a Value) -> Self {
QuotedValue { value }
}
}
impl AsRef<Value> for QuotedValue<'_> {
fn as_ref(&self) -> &Value {
self.value
}
}
impl<'a> From<QuotedValue<'a>> for Cow<'a, str> {
fn from(value: QuotedValue<'a>) -> Self {
match value.value {
Scalar(value) => yash_quote::quote(value),
Array(_values) => value.to_string().into(),
}
}
}