use super::*;
use serde::de::{self, Deserializer, MapAccess, Visitor};
use serde::ser::{SerializeMap, Serializer};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fmt;
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AccountRaw {
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
pub nonce: ValueSubTree,
pub balance: ValueSubTree,
pub storage: BTreeMap<String, ValueSubTree>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub esdt: Option<BTreeMap<String, ValueSubTree>>,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option<ValueSubTree>,
}
pub enum CheckStorageRaw {
Star,
Equal(BTreeMap<String, ValueSubTree>),
}
impl CheckStorageRaw {
pub fn is_star(&self) -> bool {
matches!(self, CheckStorageRaw::Star)
}
}
impl Serialize for CheckStorageRaw {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
CheckStorageRaw::Star => serializer.serialize_str("*"),
CheckStorageRaw::Equal(m) => {
let mut map = serializer.serialize_map(Some(m.len()))?;
for (k, v) in m {
map.serialize_entry(k, v)?;
}
map.end()
},
}
}
}
struct CheckStorageRawVisitor;
impl<'de> Visitor<'de> for CheckStorageRawVisitor {
type Value = CheckStorageRaw;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("serialized object JSON representation of log check")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if value == "*" {
Ok(CheckStorageRaw::Star)
} else {
Err(de::Error::custom("only '*' allowed as logs string value"))
}
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = BTreeMap::<String, ValueSubTree>::new();
while let Some((key, value)) = access.next_entry()? {
map.insert(key, value);
}
Ok(CheckStorageRaw::Equal(map))
}
}
impl<'de> Deserialize<'de> for CheckStorageRaw {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(CheckStorageRawVisitor)
}
}
pub enum CheckEsdtRaw {
Star,
Equal(BTreeMap<String, ValueSubTree>),
}
impl CheckEsdtRaw {
pub fn is_star(&self) -> bool {
matches!(self, CheckEsdtRaw::Star)
}
}
impl Serialize for CheckEsdtRaw {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
CheckEsdtRaw::Star => serializer.serialize_str("*"),
CheckEsdtRaw::Equal(m) => {
let mut map = serializer.serialize_map(Some(m.len()))?;
for (k, v) in m {
map.serialize_entry(k, v)?;
}
map.end()
},
}
}
}
struct CheckEsdtRawVisitor;
impl<'de> Visitor<'de> for CheckEsdtRawVisitor {
type Value = CheckEsdtRaw;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("serialized object JSON representation of esdt check")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if value == "*" {
Ok(CheckEsdtRaw::Star)
} else {
Err(de::Error::custom("only '*' allowed as esdt string value"))
}
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = BTreeMap::<String, ValueSubTree>::new();
while let Some((key, value)) = access.next_entry()? {
map.insert(key, value);
}
Ok(CheckEsdtRaw::Equal(map))
}
}
impl<'de> Deserialize<'de> for CheckEsdtRaw {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(CheckEsdtRawVisitor)
}
}
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CheckAccountRaw {
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(default)]
#[serde(skip_serializing_if = "ValueSubTree::is_empty_string")]
pub nonce: ValueSubTree,
#[serde(default)]
#[serde(skip_serializing_if = "ValueSubTree::is_empty_string")]
pub balance: ValueSubTree,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub esdt: Option<CheckEsdtRaw>,
pub storage: CheckStorageRaw,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub code: Option<ValueSubTree>,
#[serde(default)]
#[serde(skip_serializing_if = "ValueSubTree::is_empty_string")]
pub async_call_data: ValueSubTree,
}
pub enum CheckAccountRawOrNothing {
Some(CheckAccountRaw),
Nothing,
}
struct CheckAccountRawOrNothingVisitor;
impl<'de> Visitor<'de> for CheckAccountRawOrNothingVisitor {
type Value = CheckAccountRawOrNothing;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("CheckAccountRaw or nothing")
}
fn visit_str<E>(self, _value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(CheckAccountRawOrNothing::Nothing)
}
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
Ok(CheckAccountRawOrNothing::Some(Deserialize::deserialize(
de::value::MapAccessDeserializer::new(map),
)?))
}
}
impl<'de> Deserialize<'de> for CheckAccountRawOrNothing {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(CheckAccountRawOrNothingVisitor)
}
}
pub struct CheckAccountsRaw {
pub other_accounts_allowed: bool,
pub accounts: BTreeMap<String, CheckAccountRaw>,
}
impl Serialize for CheckAccountsRaw {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut map = serializer.serialize_map(Some(self.accounts.len()))?;
for (k, v) in self.accounts.iter() {
map.serialize_entry(k, v)?;
}
if self.other_accounts_allowed {
map.serialize_entry("+", "")?;
}
map.end()
}
}
struct CheckAccountRawsVisitor;
impl<'de> Visitor<'de> for CheckAccountRawsVisitor {
type Value = CheckAccountsRaw;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("serialized CheckAccountsRaw")
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut accounts = BTreeMap::<String, CheckAccountRaw>::new();
let mut other_accounts_allowed = false;
while let Some((key, value)) = access.next_entry()? {
if key == "+" {
other_accounts_allowed = true;
} else if let CheckAccountRawOrNothing::Some(check_account) = value {
accounts.insert(key, check_account);
} else {
return Err(de::Error::custom("invalid CheckAccountRaw"));
}
}
Ok(CheckAccountsRaw {
accounts,
other_accounts_allowed,
})
}
}
impl<'de> Deserialize<'de> for CheckAccountsRaw {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(CheckAccountRawsVisitor)
}
}