2022-01-21 00:52:03 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::fmt::{Debug, Display, Error, Formatter};
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
use crate::lang::TypePrimitive;
|
2022-01-21 00:52:03 +00:00
|
|
|
//use crate::lang::RuntimeError;
|
|
|
|
//use crate::processing::OpGetter;
|
|
|
|
|
|
|
|
/// general type object for MPS
|
|
|
|
#[derive(Clone, Debug, Default)]
|
2022-07-01 21:20:52 +01:00
|
|
|
pub struct Item {
|
|
|
|
fields: HashMap<String, TypePrimitive>,
|
2022-01-21 00:52:03 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
impl Item {
|
2022-01-21 00:52:03 +00:00
|
|
|
pub fn new() -> Self {
|
|
|
|
Self::default()
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
pub fn field(&self, name: &str) -> Option<&'_ TypePrimitive> {
|
2022-01-21 00:52:03 +00:00
|
|
|
self.fields.get(name)
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
pub fn set_field(&mut self, name: &str, value: TypePrimitive) -> Option<TypePrimitive> {
|
2022-01-21 00:52:03 +00:00
|
|
|
self.fields.insert(name.to_owned(), value)
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
pub fn set_field_chain(&mut self, name: &str, value: TypePrimitive) -> &mut Self {
|
2022-01-21 00:52:03 +00:00
|
|
|
self.set_field(name, value);
|
2022-05-14 19:24:18 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
pub fn set_field_chain2(mut self, name: &str, value: TypePrimitive) -> Self {
|
2022-05-14 19:24:18 +01:00
|
|
|
self.set_field(name, value);
|
2022-01-21 00:52:03 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
pub fn remove_field(&mut self, name: &str) -> Option<TypePrimitive> {
|
2022-01-21 00:52:03 +00:00
|
|
|
self.fields.remove(name)
|
|
|
|
}
|
2022-02-20 01:17:31 +00:00
|
|
|
|
2022-02-23 16:33:45 +00:00
|
|
|
pub fn iter(&self) -> impl Iterator<Item = &String> {
|
2022-02-20 01:17:31 +00:00
|
|
|
self.fields.keys()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn len(&self) -> usize {
|
|
|
|
self.fields.len()
|
|
|
|
}
|
2022-07-30 05:05:03 +01:00
|
|
|
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
|
|
self.fields.is_empty()
|
|
|
|
}
|
2022-01-21 00:52:03 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
impl Display for Item {
|
2022-01-21 00:52:03 +00:00
|
|
|
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
2022-07-01 21:20:52 +01:00
|
|
|
write!(f, "Item[({} fields)]", self.fields.len())
|
2022-01-21 00:52:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
impl std::hash::Hash for Item {
|
2022-02-03 21:56:42 +00:00
|
|
|
fn hash<H>(&self, state: &mut H)
|
|
|
|
where
|
|
|
|
H: std::hash::Hasher,
|
|
|
|
{
|
2022-02-02 20:53:57 +00:00
|
|
|
// hashing is order-dependent, so the pseudo-random sorting of HashMap keys
|
|
|
|
// prevents it from working correctly without sorting
|
|
|
|
let mut keys: Vec<_> = self.fields.keys().collect();
|
|
|
|
keys.as_mut_slice().sort();
|
|
|
|
for key in keys {
|
|
|
|
let val = self.fields.get(key).unwrap();
|
|
|
|
key.hash(state);
|
|
|
|
val.hash(state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
impl std::cmp::PartialEq for Item {
|
2022-02-02 20:53:57 +00:00
|
|
|
/*fn eq(&self, other: &Self) -> bool {
|
|
|
|
for (key, val) in self.fields.iter() {
|
|
|
|
if let Some(other_val) = other.fields.get(key) {
|
|
|
|
if other_val != val {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}*/
|
|
|
|
|
|
|
|
fn eq(&self, other: &Self) -> bool {
|
|
|
|
self.fields == other.fields
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
impl std::cmp::Eq for Item {}
|
2022-02-02 20:53:57 +00:00
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
/*pub(crate) trait ItemRuntimeUtil {
|
|
|
|
fn get_field_runtime(&self, name: &str, op: &mut OpGetter) -> Result<&TypePrimitive, RuntimeError>;
|
2022-01-21 00:52:03 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 21:20:52 +01:00
|
|
|
impl ItemRuntimeUtil for Item {
|
|
|
|
fn get_field_runtime(&self, name: &str, op: &mut OpGetter) -> Result<&TypePrimitive, RuntimeError> {
|
2022-01-21 00:52:03 +00:00
|
|
|
match self.field(name) {
|
|
|
|
Some(item) => Ok(item),
|
|
|
|
None => Err(RuntimeError{
|
|
|
|
line: 0,
|
|
|
|
op: op(),
|
|
|
|
msg: format!("Field {} not found on item", name),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|