use super::Entry;
use crate::entry::{string_is_array, ParseItem, Statement};
use crate::error::{ParseStringError, SerdeParseError};
use crate::VdfError;
use serde::de::{Error, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use std::borrow::Cow;
use std::fmt::Formatter;
use std::ops::{Deref, DerefMut};
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Default)]
#[serde(transparent)]
pub struct Value(String);
impl From<Cow<'_, str>> for Value {
fn from(value: Cow<'_, str>) -> Value {
Value(value.into())
}
}
impl From<&'_ str> for Value {
fn from(value: &str) -> Value {
Value(value.into())
}
}
impl From<String> for Value {
fn from(value: String) -> Value {
Value(value)
}
}
impl From<Statement> for Value {
fn from(value: Statement) -> Value {
Value(value.into())
}
}
impl From<Value> for Entry {
fn from(value: Value) -> Self {
Entry::Value(value)
}
}
impl From<Value> for String {
fn from(value: Value) -> Self {
value.0
}
}
impl Deref for Value {
type Target = str;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Value {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Value {
pub fn to<T: ParseItem>(self) -> Result<T, ParseStringError> {
T::from_str(&self.0)
}
}
impl<'de> Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ValueVisitor;
impl Visitor<'_> for ValueVisitor {
type Value = String;
fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
write!(formatter, "any string like value")
}
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.to_string())
}
fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.to_string())
}
fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.to_string())
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.into())
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v)
}
fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: Error,
{
Ok(if v { "1".into() } else { "0".into() })
}
}
deserializer.deserialize_str(ValueVisitor).map(Value)
}
}
impl<'de> Deserializer<'de> for Value {
type Error = VdfError;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if let Ok(int) = i64::from_str(&self.0) {
return visitor.visit_i64(int);
}
if let Ok(float) = f64::from_str(&self.0) {
return visitor.visit_f64(float);
}
if string_is_array(&self.0) {
return self.deserialize_seq(visitor);
}
visitor.visit_string(self.0)
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_bool(self.to()?)
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i8(self.to()?)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i16(self.to()?)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i32(self.to()?)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_i64(self.to()?)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u8(self.to()?)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u16(self.to()?)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u32(self.to()?)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_u64(self.to()?)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_f32(self.to()?)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_f64(self.to()?)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
let mut chars = self.0.chars();
match (chars.next(), chars.next()) {
(Some(_), None) => Ok(()),
_ => Err(SerdeParseError::new("char", &self.0, 0..0, "")),
}?;
visitor.visit_str(&self.0)
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_str(&self.0)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_string(self.0)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_bytes(self.0.as_bytes())
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_byte_buf(self.0.into_bytes())
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if self.0.is_empty() {
return visitor.visit_none();
}
visitor.visit_some(self)
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if !self.0.is_empty() {
return Err(SerdeParseError::new("unit", self.0.as_ref(), 0..0, "").into());
}
visitor.visit_unit()
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
if !self.0.is_empty() {
return Err(SerdeParseError::new("unit", self.0.as_ref(), 0..0, "").into());
}
visitor.visit_unit()
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_seq<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
Err(SerdeParseError::new("seq", self.0.as_ref(), 0..0, "").into())
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
Err(SerdeParseError::new("map", self.0.as_ref(), 0..0, "").into())
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
Err(SerdeParseError::new("struct", self.0.as_ref(), 0..0, "").into())
}
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
Err(SerdeParseError::new("map", self.0.as_ref(), 0..0, "").into())
}
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
}
#[cfg(test)]
#[track_caller]
fn unwrap_err<T>(r: Result<T, crate::VdfError>) -> T {
r.map_err(miette::Error::from).unwrap()
}
#[test]
fn test_serde_value() {
let j = r#"1"#;
assert_eq!(Value("1".into()), unwrap_err(crate::from_str(j)));
let j = r#""foo bar""#;
assert_eq!(Value("foo bar".into()), unwrap_err(crate::from_str(j)));
}
#[test]
fn test_serde_from_value() {
let j = Value::from("1");
assert_eq!(true, unwrap_err(crate::from_entry(j.into())));
}