Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  map.rs

  Sprache: Rust
 

use core::{
    cmp::{Eq, Ordering},
    hash::{Hash, Hasher},
    iter::FromIterator,
    ops::{Index, IndexMut},
};

use serde_derive::{Deserialize, Serialize};

use super::Value;

/// A [`Value`] to [`Value`] map.
///
/// This structure either uses a [`BTreeMap`](alloc::collections::BTreeMap) or the
/// [`IndexMap`](indexmap::IndexMap) internally.
/// The latter can be used by enabling the `indexmap` feature. This can be used
/// to preserve the order of the parsed map.
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[serde(transparent)]
pub struct Map(pub(crate) MapInner);

#[cfg(not(feature = "indexmap"))]
type MapInner = alloc::collections::BTreeMap<Value, Value>;
#[cfg(feature = "indexmap")]
type MapInner = indexmap::IndexMap<Value, Value, std::collections::hash_map::RandomState>;

impl Map {
    /// Creates a new, empty [`Map`].
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    /// Returns the number of elements in the map.
    #[must_use]
    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Returns `true` if `self.len() == 0`, `false` otherwise.
    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    /// Immutably looks up an element by its `key`.
    #[must_use]
    pub fn get(&self, key: &Value) -> Option<&Value> {
        self.0.get(key)
    }

    /// Mutably looks up an element by its `key`.
    pub fn get_mut(&mut self, key: &Value) -> Option<&mut Value> {
        self.0.get_mut(key)
    }

    /// Inserts a new element, returning the previous element with this `key` if
    /// there was any.
    pub fn insert(&mut self, key: impl Into<Value>, value: impl Into<Value>) -> Option<Value> {
        self.0.insert(key.into(), value.into())
    }

    /// Removes an element by its `key`.
    pub fn remove(&mut self, key: &Value) -> Option<Value> {
        #[cfg(feature = "indexmap")]
        {
            self.0.shift_remove(key)
        }
        #[cfg(not(feature = "indexmap"))]
        {
            self.0.remove(key)
        }
    }

    /// Iterate all key-value pairs.
    #[must_use]
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&Value, &Value)> {
        self.0.iter()
    }

    /// Iterate all key-value pairs mutably.
    #[must_use]
    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (&Value, &<span style='color:red'>mut Value)> {
        self.0.iter_mut()
    }

    /// Iterate all keys.
    #[must_use]
    pub fn keys(&self) -> impl DoubleEndedIterator<Item = &Value> {
        self.0.keys()
    }

    /// Iterate all values.
    #[must_use]
    pub fn values(&self) -> impl DoubleEndedIterator<Item = &Value> {
        self.0.values()
    }

    /// Iterate all values mutably.
    #[must_use]
    pub fn values_mut(&mut self) -> impl DoubleEndedIterator<Item = & style='color:red'>mut Value> {
        self.0.values_mut()
    }

    /// Retains only the elements specified by the `keep` predicate.
    ///
    /// In other words, remove all pairs `(k, v)` for which `keep(&k, &mut v)`
    /// returns `false`.
    ///
    /// The elements are visited in iteration order.
    pub fn retain<F>(&mut self, keep: F)
    where
        F: FnMut(&Value, &mut Value) -> bool,
    {
        self.0.retain(keep);
    }
}

impl Index<&Value> for Map {
    type Output = Value;

    #[allow(clippy::expect_used)]
    fn index(&self, index: &Value) -> &Self::Output {
        self.get(index).expect("no entry found for key")
    }
}

impl IndexMut<&Value> for Map {
    #[allow(clippy::expect_used)]
    fn index_mut(&mut self, index: &Value) -> &mut Self::Output {
        self.get_mut(index).expect("no entry found for key")
    }
}

impl IntoIterator for Map {
    type Item = (Value, Value);

    type IntoIter = <MapInner as IntoIterator>::IntoIter;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

impl<K: Into<Value>, V: Into<Value>> FromIterator<(K, V)> for Map {
    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
        Map(iter
            .into_iter()
            .map(|(key, value)| (key.into(), value.into()))
            .collect())
    }
}

/// Note: equality is only given if both values and order of values match
impl PartialEq for Map {
    fn eq(&self, other: &Map) -> bool {
        self.cmp(other).is_eq()
    }
}

/// Note: equality is only given if both values and order of values match
impl Eq for Map {}

impl PartialOrd for Map {
    fn partial_cmp(&self, other: &Map) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for Map {
    fn cmp(&self, other: &Map) -> Ordering {
        self.iter().cmp(other.iter())
    }
}

impl Hash for Map {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.iter().for_each(|x| x.hash(state));
    }
}

#[cfg(test)]
mod tests {
    use alloc::{vec, vec::Vec};

    use super::{Map, Value};

    #[test]
    fn map_usage() {
        let mut map = Map::new();
        assert_eq!(map.len(), 0);
        assert!(map.is_empty());

        map.insert("a"42);
        assert_eq!(map.len(), 1);
        assert!(!map.is_empty());

        assert_eq!(map.keys().collect::<Vec<_>>(), vec![&Value::from("a")]);
        assert_eq!(map.values().collect::<Vec<_>>(), vec![&Value::from(42)]);
        assert_eq!(
            map.iter().collect::<Vec<_>>(),
            vec![(&Value::from("a"), &Value::from(42))]
        );

        assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
        assert_eq!(map.get(&Value::from("b")), None);
        assert_eq!(map.get_mut(&Value::from("a")), Some(&>mut Value::from(42)));
        assert_eq!(map.get_mut(&Value::from("b")), None);

        map[&Value::from("a")] = Value::from(24);
        assert_eq!(&map[&Value::from("a")], &Value::from(24));

        for (key, value) in map.iter_mut() {
            if key == &Value::from("a") {
                *value = Value::from(42);
            }
        }
        assert_eq!(&map[&Value::from("a")], &Value::from(42));

        map.values_mut().for_each(|value| *value = Value::from(24));
        assert_eq!(&map[&Value::from("a")], &Value::from(24));

        map.insert("b"42);
        assert_eq!(map.len(), 2);
        assert!(!map.is_empty());
        assert_eq!(map.get(&Value::from("a")), Some(&Value::from(24)));
        assert_eq!(map.get(&Value::from("b")), Some(&Value::from(42)));

        map.retain(|key, value| {
            if key == &Value::from("a") {
                *value = Value::from(42);
                true
            } else {
                false
            }
        });
        assert_eq!(map.len(), 1);
        assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
        assert_eq!(map.get(&Value::from("b")), None);

        assert_eq!(map.remove(&Value::from("b")), None);
        assert_eq!(map.remove(&Value::from("a")), Some(Value::from(42)));
        assert_eq!(map.remove(&Value::from("a")), None);
    }

    #[cfg(feature = "std")]
    #[test]
    fn map_hash() {
        assert_same_hash(&Map::new(), &Map::new());
        assert_same_hash(
            &[("a"42)].into_iter().collect(),
            &[("a"42)].into_iter().collect(),
        );
        assert_same_hash(
            &[("b"24), ("c"42)].into_iter().collect(),
            &[("b"24), ("c"42)].into_iter().collect(),
        );
    }

    #[cfg(feature = "std")]
    fn assert_same_hash(a: &Map, b: &Map) {
        use core::hash::{Hash, Hasher};
        use std::collections::hash_map::DefaultHasher;

        assert_eq!(a, b);
        assert!(a.cmp(b).is_eq());
        assert_eq!(a.partial_cmp(b), Some(core::cmp::Ordering::Equal));

        let mut hasher = DefaultHasher::new();
        a.hash(&mut hasher);
        let h1 = hasher.finish();

        let mut hasher = DefaultHasher::new();
        b.hash(&mut hasher);
        let h2 = hasher.finish();

        assert_eq!(h1, h2);
    }

    #[test]
    #[should_panic(expected = "no entry found for key")]
    fn map_index_panic() {
        let _ = &Map::new()[&Value::Unit];
    }

    #[test]
    #[should_panic(expected = "no entry found for key")]
    fn map_index_mut_panic() {
        let _ = &mut Map::new()[&Value::Unit];
    }
}

Messung V0.5 in Prozent
C=90 H=95 G=92

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002