use serde::{Serialize, Serializer, ser::SerializeSeq};
use std::borrow::Cow;
pub(crate) const TOKEN: &str = "$ser_nix::private::Literal";
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NixLiteral<'a>(Cow<'a, str>);
impl<'a> NixLiteral<'a> {
pub fn new(expr: &'a str) -> Self {
NixLiteral(Cow::Borrowed(expr))
}
pub fn as_str(&self) -> &str {
&self.0
}
pub fn into_string(self) -> String {
self.0.into_owned()
}
}
impl From<String> for NixLiteral<'static> {
fn from(expr: String) -> Self {
NixLiteral(Cow::Owned(expr))
}
}
impl<'a> From<&'a str> for NixLiteral<'a> {
fn from(expr: &'a str) -> Self {
NixLiteral(Cow::Borrowed(expr))
}
}
impl<'a> From<&'a String> for NixLiteral<'a> {
fn from(expr: &'a String) -> Self {
NixLiteral(Cow::Borrowed(expr.as_str()))
}
}
impl AsRef<str> for NixLiteral<'_> {
fn as_ref(&self) -> &str {
&self.0
}
}
fn serialize_literal<S>(expr: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_newtype_struct(TOKEN, expr)
}
impl Serialize for NixLiteral<'_> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_literal(&self.0, serializer)
}
}
pub fn as_literal<S>(value: &str, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serialize_literal(value, serializer)
}
pub fn as_optional_literal<S>(value: &Option<String>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(v) => serialize_literal(v, serializer),
None => serializer.serialize_none(),
}
}
pub fn as_literal_seq<T, S>(exprs: &[T], s: S) -> Result<S::Ok, S::Error>
where
T: AsRef<str>,
S: Serializer,
{
let mut seq = s.serialize_seq(Some(exprs.len()))?;
for expr in exprs {
seq.serialize_element(&NixLiteral::new(expr.as_ref()))?;
}
seq.end()
}