use std::fmt;
use std::fmt::Display;
use serde::de::{Deserialize, Deserializer, Visitor};
use crate::error::{ConfigError, Result, Unexpected};
use crate::map::Map;
/// Underlying kind of the configuration value.
///
/// Standard operations on a `Value` by users of this crate do not require
/// knowledge of `ValueKind`. Introspection of underlying kind is only required
/// when the configuration values are unstructured or do not have known types.
#[derive(Debug, Clone, PartialEq)]
pub enum ValueKind {
Nil,
Boolean(bool),
I64(i64),
I128(i128),
U64(u64),
U128(u128),
Float(f64),
String(String),
Table(Table),
Array(Array),
}
pub type Array = Vec<Value>;
pub type Table = Map<String, Value>;
impl Default for ValueKind {
fn default() -> Self {
Self::Nil
}
}
impl<T> From<Option<T>> for ValueKind
where
T: Into<Self>,
{
fn from(value: Option<T>) -> Self {
match value {
Some(value) => value.into(),
None => Self::Nil,
}
}
}
impl From<String> for ValueKind {
fn from(value: String) -> Self {
Self::String(value)
}
}
impl<'a> From<&'a str> for ValueKind {
fn from(value: &'a str) -> Self {
Self::String(value.into())
}
}
impl From<i8> for ValueKind {
fn from(value: i8) -> Self {
Self::I64(value.into())
}
}
impl From<i16> for ValueKind {
fn from(value: i16) -> Self {
Self::I64(value.into())
}
}
impl From<i32> for ValueKind {
fn from(value: i32) -> Self {
Self::I64(value.into())
}
}
impl From<i64> for ValueKind {
fn from(value: i64) -> Self {
Self::I64(value)
}
}
impl From<i128> for ValueKind {
fn from(value: i128) -> Self {
Self::I128(value)
}
}
impl From<u8> for ValueKind {
fn from(value: u8) -> Self {
Self::U64(value.into())
}
}
impl From<u16> for ValueKind {
fn from(value: u16) -> Self {
Self::U64(value.into())
}
}
impl From<u32> for ValueKind {
fn from(value: u32) -> Self {
Self::U64(value.into())
}
}
impl From<u64> for ValueKind {
fn from(value: u64) -> Self {
Self::U64(value)
}
}
impl From<u128> for ValueKind {
fn from(value: u128) -> Self {
Self::U128(value)
}
}
impl From<f64> for ValueKind {
fn from(value: f64) -> Self {
Self::Float(value)
}
}
impl From<bool> for ValueKind {
fn from(value: bool) -> Self {
Self::Boolean(value)
}
}
impl<T> From<Map<String, T>> for ValueKind
where
T: Into<Value>,
{
fn from(values: Map<String, T>) -> Self {
let t = values.into_iter().map(|(k, v)| (k, v.into())).collect();
Self::Table(t)
}
}
impl<T> From<Vec<T>> for ValueKind
where
T: Into<Value>,
{
fn from(values: Vec<T>) -> Self {
Self::Array(values.into_iter().map(T::into).collect())
}
}
impl Display for ValueKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Self::String(ref value) => write!(f, "{}", value),
Self::Boolean(value) => write!(f, "{}", value),
Self::I64(value) => write!(f, "{}", value),
Self::I128(value) => write!(f, "{}", value),
Self::U64(value) => write!(f, "{}", value),
Self::U128(value) => write!(f, "{}", value),
Self::Float(value) => write!(f, "{}", value