use chain_impl_mockchain::value;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{fmt, str::FromStr};
use value::ValueError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Value(value::Value);
impl Value {
#[inline]
#[must_use]
pub fn as_u64(self) -> u64 {
self.0 .0
}
#[inline]
pub fn saturating_add(self, other: Self) -> Self {
Value(self.0.saturating_add(other.0))
}
#[inline]
pub fn checked_add(self, other: Self) -> Result<Self, ValueError> {
self.0.checked_add(other.0).map(Value)
}
}
impl fmt::Display for Value {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl FromStr for Value {
type Err = std::num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.parse().map(|v| Value(value::Value(v)))
}
}
impl AsRef<value::Value> for Value {
fn as_ref(&self) -> &value::Value {
&self.0
}
}
impl From<value::Value> for Value {
fn from(v: value::Value) -> Self {
Value(v)
}
}
impl From<Value> for value::Value {
fn from(v: Value) -> Self {
v.0
}
}
impl From<u64> for Value {
fn from(v: u64) -> Self {
Value(value::Value(v))
}
}
impl From<Value> for u64 {
fn from(value: Value) -> u64 {
(value.0).0
}
}
impl Serialize for Value {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.as_ref().serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Value {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let v = u64::deserialize(deserializer)?;
Ok(Value(value::Value(v)))
}
}
#[derive(Deserialize, Serialize)]
#[serde(transparent, remote = "value::Value")]
pub struct ValueDef(u64);
#[cfg(test)]
mod test {
use super::*;
use quickcheck::{Arbitrary, Gen, TestResult};
impl Arbitrary for Value {
fn arbitrary<G>(g: &mut G) -> Self
where
G: Gen,
{
Value(value::Value(u64::arbitrary(g)))
}
}
#[test]
fn value_display_as_u64() {
const VALUE: u64 = 928_170;
let value = Value(value::Value(VALUE));
assert_eq!(value.to_string(), VALUE.to_string());
}
#[test]
fn value_serde_as_u64() {
const VALUE: u64 = 928_170;
let value = Value(value::Value(VALUE));
assert_eq!(
serde_yaml::to_string(&value).unwrap(),
format!("---\n{}\n", VALUE)
);
}
quickcheck! {
fn value_display_parse(value: Value) -> TestResult {
let s = value.to_string();
let value_dec: Value = s.parse().unwrap();
TestResult::from_bool(value_dec == value)
}
fn value_serde_human_readable_encode_decode(value: Value) -> TestResult {
let s = serde_yaml::to_string(&value).unwrap();
let value_dec: Value = serde_yaml::from_str(&s).unwrap();
TestResult::from_bool(value_dec == value)
}
fn value_serde_binary_encode_decode(value: Value) -> TestResult {
let s = bincode::serialize(&value).unwrap();
let value_dec: Value = bincode::deserialize(&s).unwrap();
TestResult::from_bool(value_dec == value)
}
}
}