// 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 } }