use std::{collections::BTreeMap, convert::TryFrom};
use iso8601::DateTime;
mod de;
mod ser;
pub(crate) use ser::Serializer;
pub fn to_value<T>(value: T) -> crate::Result<Value>
where
T: serde::Serialize,
{
value.serialize(Serializer)
}
pub fn from_value<T>(value: Value) -> crate::Result<T>
where
T: serde::de::DeserializeOwned,
{
T::deserialize(value)
}
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
Int(i32),
Int64(i64),
Bool(bool),
String(String),
Double(f64),
DateTime(DateTime),
Base64(Vec<u8>),
Struct(BTreeMap<String, Value>),
Array(Vec<Value>),
Nil,
}
impl Value {
pub fn as_i32(&self) -> Option<i32> {
match *self {
Value::Int(i) => Some(i),
_ => None,
}
}
pub fn as_i64(&self) -> Option<i64> {
match *self {
Value::Int(i) => Some(i64::from(i)),
Value::Int64(i) => Some(i),
_ => None,
}
}
pub fn as_bool(&self) -> Option<bool> {
match *self {
Value::Bool(b) => Some(b),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match *self {
Value::String(ref s) => Some(s),
_ => None,
}
}
pub fn as_f64(&self) -> Option<f64> {
match *self {
Value::Double(d) => Some(d),
_ => None,
}
}
pub fn as_datetime(&self) -> Option<DateTime> {
match *self {
Value::DateTime(dt) => Some(dt),
_ => None,
}
}
pub fn as_bytes(&self) -> Option<&[u8]> {
match *self {
Value::Base64(ref data) => Some(data),
_ => None,
}
}
pub fn as_struct(&self) -> Option<&BTreeMap<String, Value>> {
match *self {
Value::Struct(ref map) => Some(map),
_ => None,
}
}
pub fn as_array(&self) -> Option<&[Value]> {
match *self {
Value::Array(ref array) => Some(array),
_ => None,
}
}
}
impl From<i32> for Value {
fn from(other: i32) -> Self {
Value::Int(other)
}
}
impl<'a> TryFrom<&'a Value> for i32 {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Int(i) => Ok(*i),
_ => Err(()),
}
}
}
impl From<i64> for Value {
fn from(other: i64) -> Self {
Value::Int64(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a i64 {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Int64(i) => Ok(i),
_ => Err(()),
}
}
}
impl From<bool> for Value {
fn from(other: bool) -> Self {
Value::Bool(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a bool {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Bool(i) => Ok(i),
_ => Err(()),
}
}
}
impl From<String> for Value {
fn from(other: String) -> Self {
Value::String(other)
}
}
impl<'a> TryFrom<&'a Value> for String {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
if let Some(val) = value.as_str() {
Ok(val.to_string())
} else {
Err(())
}
}
}
impl From<&str> for Value {
fn from(other: &str) -> Self {
Value::String(other.to_string())
}
}
impl<'a> TryFrom<&'a Value> for &'a str {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
if let Some(val) = value.as_str() {
Ok(val)
} else {
Err(())
}
}
}
impl From<f64> for Value {
fn from(other: f64) -> Self {
Value::Double(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a f64 {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Double(i) => Ok(i),
_ => Err(()),
}
}
}
impl From<DateTime> for Value {
fn from(other: DateTime) -> Self {
Value::DateTime(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a DateTime {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::DateTime(i) => Ok(i),
_ => Err(()),
}
}
}
impl From<Vec<Value>> for Value {
fn from(other: Vec<Value>) -> Value {
Value::Array(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a Vec<Value> {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Array(i) => Ok(i),
_ => Err(()),
}
}
}
impl From<BTreeMap<String, Value>> for Value {
fn from(other: BTreeMap<String, Value>) -> Value {
Value::Struct(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a BTreeMap<String, Value> {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Struct(i) => Ok(i),
_ => Err(()),
}
}
}
impl From<Vec<u8>> for Value {
fn from(other: Vec<u8>) -> Self {
Value::Base64(other)
}
}
impl<'a> TryFrom<&'a Value> for &'a Vec<u8> {
type Error = ();
fn try_from(value: &'a Value) -> Result<Self, Self::Error> {
match value {
Value::Base64(i) => Ok(i),
_ => Err(()),
}
}
}