muss/interpreter/src/item.rs

114 lines
2.9 KiB
Rust
Raw Normal View History

use std::collections::HashMap;
use std::fmt::{Debug, Display, Error, Formatter};
2022-07-01 21:20:52 +01:00
use crate::lang::TypePrimitive;
//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-07-01 21:20:52 +01:00
impl Item {
pub fn new() -> Self {
Self::default()
}
2022-07-01 21:20:52 +01:00
pub fn field(&self, name: &str) -> Option<&'_ TypePrimitive> {
self.fields.get(name)
}
2022-07-01 21:20:52 +01:00
pub fn set_field(&mut self, name: &str, value: TypePrimitive) -> Option<TypePrimitive> {
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 {
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);
self
}
2022-07-01 21:20:52 +01:00
pub fn remove_field(&mut self, name: &str) -> Option<TypePrimitive> {
self.fields.remove(name)
}
pub fn iter(&self) -> impl Iterator<Item = &String> {
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-07-01 21:20:52 +01:00
impl Display for Item {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
2022-07-01 21:20:52 +01:00
write!(f, "Item[({} fields)]", self.fields.len())
}
}
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-07-01 21:20:52 +01:00
impl ItemRuntimeUtil for Item {
fn get_field_runtime(&self, name: &str, op: &mut OpGetter) -> Result<&TypePrimitive, RuntimeError> {
match self.field(name) {
Some(item) => Ok(item),
None => Err(RuntimeError{
line: 0,
op: op(),
msg: format!("Field {} not found on item", name),
})
}
}
}*/