use std::collections::HashMap;
use gut::prelude::*;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use crate::atom::{Point3, Vector3f};
use crate::{Atom, Molecule};
#[cfg(feature = "adhoc")]
impl Atom {
pub fn get_momentum(&self) -> Option<Point3> {
self.mass.map(|m| (m * self.velocity).into())
}
pub fn set_velocity<P: Into<Vector3f>>(&mut self, m: P) {
self.velocity = m.into();
}
pub fn velocity(&self) -> Point3 {
self.velocity.into()
}
}
#[cfg(feature = "adhoc")]
impl Molecule {
pub fn set_velocity<P: Into<Vector3f>>(&mut self, sn: usize, m: P) {
if let Some(atom) = self.get_atom_mut(sn) {
atom.set_velocity(m);
} else {
panic!("invalid sn: {}", sn);
}
}
pub fn set_velocities<T, M>(&mut self, velocities: T)
where
T: IntoIterator<Item = M>,
M: Into<Vector3f>,
{
for (sn, m) in self.serial_numbers().zip(velocities.into_iter()) {
let atom = self.get_atom_mut(sn).unwrap();
atom.set_velocity(m);
}
}
pub fn velocities(&self) -> impl Iterator<Item = Point3> + '_ {
self.atoms().map(move |(_, atom)| atom.velocity())
}
}
use serde_json::{Map, Value};
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct PropertyStore {
data: Map<String, Value>,
}
impl PropertyStore {
pub fn contains_key(&self, key: &str) -> bool {
self.data.contains_key(key)
}
pub fn load<D: DeserializeOwned>(&self, key: &str) -> Result<D> {
if let Some(value) = self.data.get(key) {
let d = serde_json::from_value(value.clone()).with_context(|| format!("Failed to deserialize data for key {:?}", key))?;
Ok(d)
} else {
bail!("Failed to get property with key {:?}", key)
}
}
pub fn store<D: Serialize>(&mut self, key: &str, value: D) -> Result<()> {
let value = serde_json::to_value(&value)?;
self.data.insert(key.into(), value);
Ok(())
}
pub fn discard(&mut self, key: &str) {
let _ = self.data.remove(key);
}
}
impl PropertyStore {
pub fn take<D: DeserializeOwned>(&mut self, key: &str) -> Result<D> {
if let Some(value) = self.data.remove(key) {
let d = serde_json::from_value(value).with_context(|| format!("Failed to deserialize data for key {:?}", key))?;
Ok(d)
} else {
bail!("Failed to get property with key {:?}", key)
}
}
#[inline]
pub fn clear(&mut self) {
self.data.clear();
}
#[inline]
pub fn len(&self) -> usize {
self.data.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn raw_map(&self) -> &Map<String, Value> {
&self.data
}
pub fn raw_map_mut(&mut self) -> &mut Map<String, Value> {
&mut self.data
}
}
#[test]
fn test_atom_store() {
let mut x = PropertyStore::default();
let d = [1, 2, 3];
x.store("k", d);
let x: [usize; 3] = x.load("k").unwrap();
assert_eq!(d, x);
#[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize)]
struct A {
a: usize,
b: isize,
}
let a = A::default();
let mut x = PropertyStore::default();
x.store("a", &a);
let a_loaded: A = x.load("a").unwrap();
assert_eq!(a_loaded, a);
let a_took: A = x.take("a").unwrap();
assert_eq!(x.contains_key("a"), false);
}