// Copyright 2018-2020 Parity Technologies (UK) Ltd.
// This file is part of cargo-contract.
//
// cargo-contract is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// cargo-contract is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with cargo-contract. If not, see .
//! SCALE Object Notation (SCON)
mod display;
mod parse;
use indexmap::IndexMap;
use crate::util;
use std::{
cmp::{
Eq,
Ordering,
},
hash::{
Hash,
Hasher,
},
iter::FromIterator,
ops::{
Index,
IndexMut,
},
str::FromStr,
};
pub use self::parse::parse_value;
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Value {
Bool(bool),
Char(char),
UInt(u128),
Int(i128),
Map(Map),
Tuple(Tuple),
String(String),
Seq(Seq),
Hex(Hex),
Literal(String),
Unit,
}
#[derive(Clone, Debug)]
pub struct Map {
ident: Option,
map: IndexMap,
}
impl Eq for Map {}
impl Hash for Map {
fn hash(&self, state: &mut H) {
self.iter().for_each(|x| x.hash(state));
}
}
impl Index<&Value> for Map {
type Output = Value;
fn index(&self, index: &Value) -> &Self::Output {
&self.map[index]
}
}
impl IndexMut<&Value> for Map {
fn index_mut(&mut self, index: &Value) -> &mut Self::Output {
self.map.get_mut(index).expect("no entry found for key")
}
}
impl Ord for Map {
fn cmp(&self, other: &Map) -> Ordering {
self.iter().cmp(other.iter())
}
}
/// Note: equality is only given if both values and order of values match
impl PartialEq for Map {
fn eq(&self, other: &Map) -> bool {
if self.map.len() != other.map.len() {
return false
}
self.iter().zip(other.iter()).all(|(a, b)| a == b)
}
}
impl PartialOrd for Map {
fn partial_cmp(&self, other: &Map) -> Option {
self.iter().partial_cmp(other.iter())
}
}
impl FromIterator<(Value, Value)> for Map {
fn from_iter>(iter: T) -> Self {
Map::new(None, IndexMap::from_iter(iter))
}
}
impl Map {
/// Creates a new, empty `Map`.
pub fn new(ident: Option<&str>, map: IndexMap) -> Map {
Map {
ident: ident.map(|s| s.to_string()),
map,
}
}
/// Return the identifier of the [`Map`].
pub fn ident(&self) -> Option {
self.ident.clone()
}
/// Iterate all key-value pairs.
pub fn iter(&self) -> impl Iterator- + DoubleEndedIterator {
self.map.iter()
}
/// Return an iterator over the map's values
pub fn values(&self) -> impl Iterator
- {
self.map.values()
}
/// Return a reference to the value stored for string key, if it is present, else None.
pub fn get_by_str(&self, key: &str) -> Option<&Value> {
self.map.get(&Value::String(key.to_string()))
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Tuple {
ident: Option,
values: Vec,
}
impl From> for Tuple {
fn from(values: Vec) -> Self {
Tuple {
ident: None,
values,
}
}
}
impl Tuple {
pub fn new(ident: Option<&str>, values: Vec) -> Self {
Tuple {
ident: ident.map(|s| s.into()),
values,
}
}
pub fn ident(&self) -> Option {
self.ident.clone()
}
/// Returns an iterator over the tuple's values
pub fn values(&self) -> impl Iterator
- {
self.values.iter()
}
}
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Seq {
elems: Vec,
}
impl From> for Seq {
fn from(elems: Vec) -> Self {
Self::new(elems)
}
}
impl Seq {
pub fn new(elems: Vec) -> Self {
Seq { elems }
}
pub fn elems(&self) -> &[Value] {
&self.elems
}
pub fn len(&self) -> usize {
self.elems.len()
}
}
#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Hex {
s: String,
bytes: Vec,
}
impl FromStr for Hex {
type Err = hex::FromHexError;
fn from_str(s: &str) -> Result {
let s = s.trim_start_matches("0x").to_string();
let bytes = util::decode_hex(&s)?;
Ok(Self { s, bytes })
}
}
impl Hex {
pub fn as_str(&self) -> &str {
&self.s
}
pub fn bytes(&self) -> &[u8] {
&self.bytes
}
}