123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- use crate::core::{OperationAttributes, OperationTransform};
- use crate::errors::OTError;
- use serde::{Deserialize, Serialize};
- use std::collections::HashMap;
- use std::fmt;
- use std::fmt::Display;
- #[derive(Debug, Clone)]
- pub struct AttributeEntry {
- pub key: AttributeKey,
- pub value: AttributeValue,
- }
- impl AttributeEntry {
- pub fn remove_value(&mut self) {
- self.value.ty = None;
- self.value.value = None;
- }
- }
- impl std::convert::From<AttributeEntry> for AttributeHashMap {
- fn from(entry: AttributeEntry) -> Self {
- let mut attributes = AttributeHashMap::new();
- attributes.insert_entry(entry);
- attributes
- }
- }
- #[derive(Default, Clone, Serialize, Deserialize, Eq, PartialEq, Debug)]
- pub struct AttributeHashMap(HashMap<AttributeKey, AttributeValue>);
- impl std::ops::Deref for AttributeHashMap {
- type Target = HashMap<AttributeKey, AttributeValue>;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
- }
- impl std::ops::DerefMut for AttributeHashMap {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.0
- }
- }
- impl AttributeHashMap {
- pub fn new() -> AttributeHashMap {
- AttributeHashMap(HashMap::new())
- }
- pub fn from_value(attribute_map: HashMap<AttributeKey, AttributeValue>) -> Self {
- Self(attribute_map)
- }
- pub fn insert<K: ToString, V: Into<AttributeValue>>(&mut self, key: K, value: V) {
- self.0.insert(key.to_string(), value.into());
- }
- pub fn insert_entry(&mut self, entry: AttributeEntry) {
- self.insert(entry.key, entry.value)
- }
- /// Set the key's value to None
- pub fn remove_value<K: AsRef<str>>(&mut self, key: K) {
- // if let Some(mut_value) = self.0.get_mut(key.as_ref()) {
- // mut_value.value = None;
- // }
- self.insert(key.as_ref().to_string(), AttributeValue::none());
- }
- /// Set all key's value to None
- pub fn remove_all_value(&mut self) {
- self.0.iter_mut().for_each(|(_, v)| {
- *v = AttributeValue::none();
- })
- }
- pub fn retain_values(&mut self, retain_keys: &[&str]) {
- self.0.iter_mut().for_each(|(k, v)| {
- if !retain_keys.contains(&k.as_str()) {
- *v = AttributeValue::none();
- }
- })
- }
- pub fn remove_key<K: AsRef<str>>(&mut self, key: K) {
- self.0.remove(key.as_ref());
- }
- /// Create a new key/value map by constructing new attributes from the other
- /// if it's not None and replace the key/value with self key/value.
- pub fn merge(&mut self, other: Option<AttributeHashMap>) {
- if other.is_none() {
- return;
- }
- let mut new_attributes = other.unwrap().0;
- self.0.iter().for_each(|(k, v)| {
- new_attributes.insert(k.clone(), v.clone());
- });
- self.0 = new_attributes;
- }
- pub fn is_empty(&self) -> bool {
- self.0.is_empty()
- }
- }
- impl Display for AttributeHashMap {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- for (key, value) in self.0.iter() {
- let _ = f.write_str(&format!("{:?}:{:?}", key, value))?;
- }
- Ok(())
- }
- }
- impl OperationAttributes for AttributeHashMap {
- fn is_empty(&self) -> bool {
- self.is_empty()
- }
- fn remove(&mut self) {
- self.retain(|_, v| v.value.is_some());
- }
- fn extend(&mut self, other: Self) {
- self.0.extend(other.0);
- }
- }
- impl OperationTransform for AttributeHashMap {
- fn compose(&self, other: &Self) -> Result<Self, OTError>
- where
- Self: Sized,
- {
- let mut attributes = self.clone();
- attributes.0.extend(other.clone().0);
- Ok(attributes)
- }
- fn transform(&self, other: &Self) -> Result<(Self, Self), OTError>
- where
- Self: Sized,
- {
- let a = self.iter().fold(AttributeHashMap::new(), |mut new_attributes, (k, v)| {
- if !other.contains_key(k) {
- new_attributes.insert(k.clone(), v.clone());
- }
- new_attributes
- });
- let b = other
- .iter()
- .fold(AttributeHashMap::new(), |mut new_attributes, (k, v)| {
- if !self.contains_key(k) {
- new_attributes.insert(k.clone(), v.clone());
- }
- new_attributes
- });
- Ok((a, b))
- }
- fn invert(&self, other: &Self) -> Self {
- let base_inverted = other.iter().fold(AttributeHashMap::new(), |mut attributes, (k, v)| {
- if other.get(k) != self.get(k) && self.contains_key(k) {
- attributes.insert(k.clone(), v.clone());
- }
- attributes
- });
- self.iter().fold(base_inverted, |mut attributes, (k, _)| {
- if other.get(k) != self.get(k) && !other.contains_key(k) {
- attributes.remove_value(k);
- }
- attributes
- })
- }
- }
- pub type AttributeKey = String;
- #[derive(Eq, PartialEq, Hash, Debug, Clone)]
- pub enum ValueType {
- IntType = 0,
- FloatType = 1,
- StrType = 2,
- BoolType = 3,
- }
- #[derive(Debug, Clone, PartialEq, Eq, Hash)]
- pub struct AttributeValue {
- pub ty: Option<ValueType>,
- pub value: Option<String>,
- }
- impl AttributeValue {
- pub fn none() -> Self {
- Self { ty: None, value: None }
- }
- pub fn from_int(val: usize) -> Self {
- let value = if val > 0_usize { Some(val.to_string()) } else { None };
- Self {
- ty: Some(ValueType::IntType),
- value,
- }
- }
- pub fn from_float(val: f64) -> Self {
- Self {
- ty: Some(ValueType::FloatType),
- value: Some(val.to_string()),
- }
- }
- pub fn from_bool(val: bool) -> Self {
- let value = if val { Some(val.to_string()) } else { None };
- Self {
- ty: Some(ValueType::BoolType),
- value,
- }
- }
- pub fn from_string(s: &str) -> Self {
- let value = if s.is_empty() { None } else { Some(s.to_string()) };
- Self {
- ty: Some(ValueType::StrType),
- value,
- }
- }
- pub fn int_value(&self) -> Option<i64> {
- let value = self.value.as_ref()?;
- Some(value.parse::<i64>().unwrap_or(0))
- }
- pub fn bool_value(&self) -> Option<bool> {
- let value = self.value.as_ref()?;
- Some(value.parse::<bool>().unwrap_or(false))
- }
- pub fn str_value(&self) -> Option<String> {
- self.value.clone()
- }
- pub fn float_value(&self) -> Option<f64> {
- let value = self.value.as_ref()?;
- Some(value.parse::<f64>().unwrap_or(0.0))
- }
- }
- impl std::convert::From<bool> for AttributeValue {
- fn from(value: bool) -> Self {
- AttributeValue::from_bool(value)
- }
- }
- impl std::convert::From<usize> for AttributeValue {
- fn from(value: usize) -> Self {
- AttributeValue::from_int(value)
- }
- }
- impl std::convert::From<&str> for AttributeValue {
- fn from(value: &str) -> Self {
- AttributeValue::from_string(value)
- }
- }
- impl std::convert::From<String> for AttributeValue {
- fn from(value: String) -> Self {
- AttributeValue::from_string(&value)
- }
- }
- #[derive(Default)]
- pub struct AttributeBuilder {
- attributes: AttributeHashMap,
- }
- impl AttributeBuilder {
- pub fn new() -> Self {
- Self::default()
- }
- pub fn insert<K: ToString, V: Into<AttributeValue>>(mut self, key: K, value: V) -> Self {
- self.attributes.insert(key, value);
- self
- }
- pub fn insert_entry(mut self, entry: AttributeEntry) -> Self {
- self.attributes.insert_entry(entry);
- self
- }
- pub fn delete<K: AsRef<str>>(mut self, key: K) -> Self {
- self.attributes.remove_value(key);
- self
- }
- pub fn build(self) -> AttributeHashMap {
- self.attributes
- }
- }
|