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


Quelle  source.rs   Sprache: unbekannt

 
//! Sources for key-value pairs.

#[cfg(feature = "kv_unstable_sval")]
extern crate sval;
#[cfg(feature = "kv_unstable_sval")]
extern crate sval_ref;

#[cfg(feature = "kv_unstable_serde")]
extern crate serde;

use kv::{Error, Key, ToKey, ToValue, Value};
use std::fmt;

/// A source of key-value pairs.
///
/// The source may be a single pair, a set of pairs, or a filter over a set of pairs.
/// Use the [`Visitor`](trait.Visitor.html) trait to inspect the structured data
/// in a source.
pub trait Source {
    /// Visit key-value pairs.
    ///
    /// A source doesn't have to guarantee any ordering or uniqueness of key-value pairs.
    /// If the given visitor returns an error then the source may early-return with it,
    /// even if there are more key-value pairs.
    ///
    /// # Implementation notes
    ///
    /// A source should yield the same key-value pairs to a subsequent visitor unless
    /// that visitor itself fails.
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error>;

    /// Get the value for a given key.
    ///
    /// If the key appears multiple times in the source then which key is returned
    /// is implementation specific.
    ///
    /// # Implementation notes
    ///
    /// A source that can provide a more efficient implementation of this method
    /// should override it.
    #[cfg(not(test))]
    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        get_default(self, key)
    }

    #[cfg(test)]
    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>>;

    /// Count the number of key-value pairs that can be visited.
    ///
    /// # Implementation notes
    ///
    /// A source that knows the number of key-value pairs upfront may provide a more
    /// efficient implementation.
    ///
    /// A subsequent call to `visit` should yield the same number of key-value pairs
    /// to the visitor, unless that visitor fails part way through.
    #[cfg(not(test))]
    fn count(&self) -> usize {
        count_default(self)
    }

    #[cfg(test)]
    fn count(&self) -> usize;
}

/// The default implemention of `Source::get`
pub(crate) fn get_default<'v>(source: &'v (impl Source + ?Sized), key: Key) -> Option<Value<'v>> {
    struct Get<'k, 'v> {
        key: Key<'k>,
        found: Option<Value<'v>>,
    }

    impl<'k, 'kvs> Visitor<'kvs> for Get<'k, 'kvs> {
        fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
            if self.key == key {
                self.found = Some(value);
            }

            Ok(())
        }
    }

    let mut get = Get { key, found: None };

    let _ = source.visit(&mut get);
    get.found
}

/// The default implementation of `Source::count`.
pub(crate) fn count_default(source: impl Source) -> usize {
    struct Count(usize);

    impl<'kvs> Visitor<'kvs> for Count {
        fn visit_pair(&mut self, _: Key<'kvs>, _: Value<'kvs>) -> Result<(), Error> {
            self.0 += 1;

            Ok(())
        }
    }

    let mut count = Count(0);
    let _ = source.visit(&mut count);
    count.0
}

impl<'a, T> Source for &'a T
where
    T: Source + ?Sized,
{
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
        Source::visit(&**self, visitor)
    }

    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        Source::get(&**self, key)
    }

    fn count(&self) -> usize {
        Source::count(&**self)
    }
}

impl<K, V> Source for (K, V)
where
    K: ToKey,
    V: ToValue,
{
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
        visitor.visit_pair(self.0.to_key(), self.1.to_value())
    }

    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        if self.0.to_key() == key {
            Some(self.1.to_value())
        } else {
            None
        }
    }

    fn count(&self) -> usize {
        1
    }
}

impl<S> Source for [S]
where
    S: Source,
{
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
        for source in self {
            source.visit(visitor)?;
        }

        Ok(())
    }

    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        for source in self {
            if let Some(found) = source.get(key.clone()) {
                return Some(found);
            }
        }

        None
    }

    fn count(&self) -> usize {
        self.len()
    }
}

impl<S> Source for Option<S>
where
    S: Source,
{
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
        if let Some(ref source) = *self {
            source.visit(visitor)?;
        }

        Ok(())
    }

    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        self.as_ref().and_then(|s| s.get(key))
    }

    fn count(&self) -> usize {
        self.as_ref().map(Source::count).unwrap_or(0)
    }
}

/// A visitor for the key-value pairs in a [`Source`](trait.Source.html).
pub trait Visitor<'kvs> {
    /// Visit a key-value pair.
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error>;
}

impl<'a, 'kvs, T> Visitor<'kvs> for &'a mut T
where
    T: Visitor<'kvs> + ?Sized,
{
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
        (**self).visit_pair(key, value)
    }
}

impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugMap<'a, 'b> {
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
        self.entry(&key, &value);
        Ok(())
    }
}

impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugList<'a, 'b> {
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
        self.entry(&(key, value));
        Ok(())
    }
}

impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugSet<'a, 'b> {
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
        self.entry(&(key, value));
        Ok(())
    }
}

impl<'a, 'b: 'a, 'kvs> Visitor<'kvs> for fmt::DebugTuple<'a, 'b> {
    fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
        self.field(&key);
        self.field(&value);
        Ok(())
    }
}

#[cfg(feature = "std")]
mod std_support {
    use super::*;
    use std::borrow::Borrow;
    use std::collections::{BTreeMap, HashMap};
    use std::hash::{BuildHasher, Hash};

    impl<S> Source for Box<S>
    where
        S: Source + ?Sized,
    {
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
            Source::visit(&**self, visitor)
        }

        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
            Source::get(&**self, key)
        }

        fn count(&self) -> usize {
            Source::count(&**self)
        }
    }

    impl<S> Source for Vec<S>
    where
        S: Source,
    {
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
            Source::visit(&**self, visitor)
        }

        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
            Source::get(&**self, key)
        }

        fn count(&self) -> usize {
            Source::count(&**self)
        }
    }

    impl<'kvs, V> Visitor<'kvs> for Box<V>
    where
        V: Visitor<'kvs> + ?Sized,
    {
        fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
            (**self).visit_pair(key, value)
        }
    }

    impl<K, V, S> Source for HashMap<K, V, S>
    where
        K: ToKey + Borrow<str> + Eq + Hash,
        V: ToValue,
        S: BuildHasher,
    {
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
            for (key, value) in self {
                visitor.visit_pair(key.to_key(), value.to_value())?;
            }
            Ok(())
        }

        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
            HashMap::get(self, key.as_str()).map(|v| v.to_value())
        }

        fn count(&self) -> usize {
            self.len()
        }
    }

    impl<K, V> Source for BTreeMap<K, V>
    where
        K: ToKey + Borrow<str> + Ord,
        V: ToValue,
    {
        fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
            for (key, value) in self {
                visitor.visit_pair(key.to_key(), value.to_value())?;
            }
            Ok(())
        }

        fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
            BTreeMap::get(self, key.as_str()).map(|v| v.to_value())
        }

        fn count(&self) -> usize {
            self.len()
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;
        use kv::value::tests::Token;
        use std::collections::{BTreeMap, HashMap};

        #[test]
        fn count() {
            assert_eq!(1, Source::count(&Box::new(("a", 1))));
            assert_eq!(2, Source::count(&vec![("a", 1), ("b", 2)]));
        }

        #[test]
        fn get() {
            let source = vec![("a", 1), ("b", 2), ("a", 1)];
            assert_eq!(
                Token::I64(1),
                Source::get(&source, Key::from_str("a")).unwrap().to_token()
            );

            let source = Box::new(Option::None::<(&str, i32)>);
            assert!(Source::get(&source, Key::from_str("a")).is_none());
        }

        #[test]
        fn hash_map() {
            let mut map = HashMap::new();
            map.insert("a", 1);
            map.insert("b", 2);

            assert_eq!(2, Source::count(&map));
            assert_eq!(
                Token::I64(1),
                Source::get(&map, Key::from_str("a")).unwrap().to_token()
            );
        }

        #[test]
        fn btree_map() {
            let mut map = BTreeMap::new();
            map.insert("a", 1);
            map.insert("b", 2);

            assert_eq!(2, Source::count(&map));
            assert_eq!(
                Token::I64(1),
                Source::get(&map, Key::from_str("a")).unwrap().to_token()
            );
        }
    }
}

/// The result of calling `Source::as_map`.
pub struct AsMap<S>(S);

/// Visit this source as a map.
pub fn as_map<S>(source: S) -> AsMap<S>
where
    S: Source,
{
    AsMap(source)
}

impl<S> Source for AsMap<S>
where
    S: Source,
{
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
        self.0.visit(visitor)
    }

    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        self.0.get(key)
    }

    fn count(&self) -> usize {
        self.0.count()
    }
}

impl<S> fmt::Debug for AsMap<S>
where
    S: Source,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut f = f.debug_map();
        self.0.visit(&mut f).map_err(|_| fmt::Error)?;
        f.finish()
    }
}

/// The result of calling `Source::as_list`
pub struct AsList<S>(S);

/// Visit this source as a list.
pub fn as_list<S>(source: S) -> AsList<S>
where
    S: Source,
{
    AsList(source)
}

impl<S> Source for AsList<S>
where
    S: Source,
{
    fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
        self.0.visit(visitor)
    }

    fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
        self.0.get(key)
    }

    fn count(&self) -> usize {
        self.0.count()
    }
}

impl<S> fmt::Debug for AsList<S>
where
    S: Source,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut f = f.debug_list();
        self.0.visit(&mut f).map_err(|_| fmt::Error)?;
        f.finish()
    }
}

#[cfg(feature = "kv_unstable_sval")]
mod sval_support {
    use super::*;

    impl<S> self::sval::Value for AsMap<S>
    where
        S: Source,
    {
        fn stream<'sval, SV: self::sval::Stream<'sval> + ?Sized>(
            &'sval self,
            stream: &mut SV,
        ) -> self::sval::Result {
            struct StreamVisitor<'a, V: ?Sized>(&'a mut V);

            impl<'a, 'kvs, V: self::sval::Stream<'kvs> + ?Sized> Visitor<'kvs> for StreamVisitor<'a, V> {
                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
                    self.0
                        .map_key_begin()
                        .map_err(|_| Error::msg("failed to stream map key"))?;
                    sval_ref::stream_ref(self.0, key)
                        .map_err(|_| Error::msg("failed to stream map key"))?;
                    self.0
                        .map_key_end()
                        .map_err(|_| Error::msg("failed to stream map key"))?;

                    self.0
                        .map_value_begin()
                        .map_err(|_| Error::msg("failed to stream map value"))?;
                    sval_ref::stream_ref(self.0, value)
                        .map_err(|_| Error::msg("failed to stream map value"))?;
                    self.0
                        .map_value_end()
                        .map_err(|_| Error::msg("failed to stream map value"))?;

                    Ok(())
                }
            }

            stream
                .map_begin(Some(self.count()))
                .map_err(|_| self::sval::Error::new())?;

            self.visit(&mut StreamVisitor(stream))
                .map_err(|_| self::sval::Error::new())?;

            stream.map_end().map_err(|_| self::sval::Error::new())
        }
    }

    impl<S> self::sval::Value for AsList<S>
    where
        S: Source,
    {
        fn stream<'sval, SV: self::sval::Stream<'sval> + ?Sized>(
            &'sval self,
            stream: &mut SV,
        ) -> self::sval::Result {
            struct StreamVisitor<'a, V: ?Sized>(&'a mut V);

            impl<'a, 'kvs, V: self::sval::Stream<'kvs> + ?Sized> Visitor<'kvs> for StreamVisitor<'a, V> {
                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
                    self.0
                        .seq_value_begin()
                        .map_err(|_| Error::msg("failed to stream seq value"))?;
                    self::sval_ref::stream_ref(self.0, (key, value))
                        .map_err(|_| Error::msg("failed to stream seq value"))?;
                    self.0
                        .seq_value_end()
                        .map_err(|_| Error::msg("failed to stream seq value"))?;

                    Ok(())
                }
            }

            stream
                .seq_begin(Some(self.count()))
                .map_err(|_| self::sval::Error::new())?;

            self.visit(&mut StreamVisitor(stream))
                .map_err(|_| self::sval::Error::new())?;

            stream.seq_end().map_err(|_| self::sval::Error::new())
        }
    }

    #[cfg(test)]
    mod tests {
        extern crate sval_derive;

        use super::*;

        use self::sval_derive::Value;

        use crate::kv::source;

        #[test]
        fn derive_stream() {
            #[derive(Value)]
            pub struct MyRecordAsMap<'a> {
                msg: &'a str,
                kvs: source::AsMap<&'a dyn Source>,
            }

            #[derive(Value)]
            pub struct MyRecordAsList<'a> {
                msg: &'a str,
                kvs: source::AsList<&'a dyn Source>,
            }
        }
    }
}

#[cfg(feature = "kv_unstable_serde")]
pub mod as_map {
    //! `serde` adapters for serializing a `Source` as a map.

    use super::*;

    use self::serde::{Serialize, Serializer};

    /// Serialize a `Source` as a map.
    pub fn serialize<T, S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
    where
        T: Source,
        S: Serializer,
    {
        as_map(source).serialize(serializer)
    }
}

#[cfg(feature = "kv_unstable_serde")]
pub mod as_list {
    //! `serde` adapters for serializing a `Source` as a list.

    use super::*;

    use self::serde::{Serialize, Serializer};

    /// Serialize a `Source` as a list.
    pub fn serialize<T, S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
    where
        T: Source,
        S: Serializer,
    {
        as_list(source).serialize(serializer)
    }
}

#[cfg(feature = "kv_unstable_serde")]
mod serde_support {
    use super::*;

    use self::serde::ser::{Error as SerError, Serialize, SerializeMap, SerializeSeq, Serializer};

    impl<T> Serialize for AsMap<T>
    where
        T: Source,
    {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            struct SerializerVisitor<'a, S>(&'a mut S);

            impl<'a, 'kvs, S> Visitor<'kvs> for SerializerVisitor<'a, S>
            where
                S: SerializeMap,
            {
                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
                    self.0
                        .serialize_entry(&key, &value)
                        .map_err(|_| Error::msg("failed to serialize map entry"))?;
                    Ok(())
                }
            }

            let mut map = serializer.serialize_map(Some(self.count()))?;

            self.visit(&mut SerializerVisitor(&mut map))
                .map_err(|_| S::Error::custom("failed to visit key-values"))?;

            map.end()
        }
    }

    impl<T> Serialize for AsList<T>
    where
        T: Source,
    {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            struct SerializerVisitor<'a, S>(&'a mut S);

            impl<'a, 'kvs, S> Visitor<'kvs> for SerializerVisitor<'a, S>
            where
                S: SerializeSeq,
            {
                fn visit_pair(&mut self, key: Key<'kvs>, value: Value<'kvs>) -> Result<(), Error> {
                    self.0
                        .serialize_element(&(key, value))
                        .map_err(|_| Error::msg("failed to serialize seq entry"))?;
                    Ok(())
                }
            }

            let mut seq = serializer.serialize_seq(Some(self.count()))?;

            self.visit(&mut SerializerVisitor(&mut seq))
                .map_err(|_| S::Error::custom("failed to visit seq"))?;

            seq.end()
        }
    }

    #[cfg(test)]
    mod tests {
        use super::*;

        use self::serde::Serialize;

        use crate::kv::source;

        #[test]
        fn derive_serialize() {
            #[derive(Serialize)]
            pub struct MyRecordAsMap<'a> {
                msg: &'a str,
                #[serde(flatten)]
                #[serde(with = "source::as_map")]
                kvs: &'a dyn Source,
            }

            #[derive(Serialize)]
            pub struct MyRecordAsList<'a> {
                msg: &'a str,
                #[serde(flatten)]
                #[serde(with = "source::as_list")]
                kvs: &'a dyn Source,
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use kv::value::tests::Token;

    #[test]
    fn source_is_object_safe() {
        fn _check(_: &dyn Source) {}
    }

    #[test]
    fn visitor_is_object_safe() {
        fn _check(_: &dyn Visitor) {}
    }

    #[test]
    fn count() {
        struct OnePair {
            key: &'static str,
            value: i32,
        }

        impl Source for OnePair {
            fn visit<'kvs>(&'kvs self, visitor: &mut dyn Visitor<'kvs>) -> Result<(), Error> {
                visitor.visit_pair(self.key.to_key(), self.value.to_value())
            }

            fn get<'v>(&'v self, key: Key) -> Option<Value<'v>> {
                get_default(self, key)
            }

            fn count(&self) -> usize {
                count_default(self)
            }
        }

        assert_eq!(1, Source::count(&("a", 1)));
        assert_eq!(2, Source::count(&[("a", 1), ("b", 2)] as &[_]));
        assert_eq!(0, Source::count(&Option::None::<(&str, i32)>));
        assert_eq!(1, Source::count(&OnePair { key: "a", value: 1 }));
    }

    #[test]
    fn get() {
        let source = &[("a", 1), ("b", 2), ("a", 1)] as &[_];
        assert_eq!(
            Token::I64(1),
            Source::get(source, Key::from_str("a")).unwrap().to_token()
        );
        assert_eq!(
            Token::I64(2),
            Source::get(source, Key::from_str("b")).unwrap().to_token()
        );
        assert!(Source::get(&source, Key::from_str("c")).is_none());

        let source = Option::None::<(&str, i32)>;
        assert!(Source::get(&source, Key::from_str("a")).is_none());
    }

    #[test]
    fn as_map() {
        let _ = crate::kv::source::as_map(("a", 1));
        let _ = crate::kv::source::as_map(&("a", 1) as &dyn Source);
    }

    #[test]
    fn as_list() {
        let _ = crate::kv::source::as_list(("a", 1));
        let _ = crate::kv::source::as_list(&("a", 1) as &dyn Source);
    }
}

[ Dauer der Verarbeitung: 0.30 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge