argmin/core/
kv.rs

1// Copyright 2018-2020 argmin developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8//! # Key Value storage
9//!
10//! A very simple key-value storage.
11//!
12//! TODOs:
13//!   * Either use something existing, or at least evaluate the performance and if necessary,
14//!     improve performance.
15
16use serde::{Deserialize, Serialize};
17use std;
18
19/// A simple key-value storage
20#[derive(Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Serialize, Deserialize)]
21pub struct ArgminKV {
22    /// The actual key value storage
23    #[serde(borrow)]
24    pub kv: Vec<(&'static str, String)>,
25}
26
27impl std::fmt::Display for ArgminKV {
28    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
29        writeln!(f, "ArgminKV")?;
30        self.kv
31            .iter()
32            .map(|(key, val)| -> std::fmt::Result { writeln!(f, "   {}: {}", key, val) })
33            .count();
34        Ok(())
35    }
36}
37
38impl ArgminKV {
39    /// Constructor
40    pub fn new() -> Self {
41        ArgminKV { kv: vec![] }
42    }
43
44    /// Push a key-value pair to the `kv` vector.
45    ///
46    /// This formats the `val` using `format!`. Therefore `T` has to implement `Display`.
47    pub fn push<T: std::fmt::Display>(&mut self, key: &'static str, val: T) -> &mut Self {
48        self.kv.push((key, format!("{}", val)));
49        self
50    }
51
52    /// Merge another `kv` into `self.kv`
53    pub fn merge(mut self, other: &mut ArgminKV) -> Self {
54        self.kv.append(&mut other.kv);
55        self
56    }
57}
58
59impl std::iter::FromIterator<(&'static str, String)> for ArgminKV {
60    fn from_iter<I: IntoIterator<Item = (&'static str, String)>>(iter: I) -> Self {
61        let mut c = ArgminKV::new();
62
63        for i in iter {
64            c.push(i.0, i.1);
65        }
66
67        c
68    }
69}
70
71impl std::iter::Extend<(&'static str, String)> for ArgminKV {
72    fn extend<I: IntoIterator<Item = (&'static str, String)>>(&mut self, iter: I) {
73        for i in iter {
74            self.push(i.0, i.1);
75        }
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    send_sync_test!(argmin_kv, ArgminKV);
84}