Auto merge of #126 - matthiasbeyer:libimagutil/add-kv-splitter, r=matthiasbeyer
Libimagutil/add kv splitter
This will be useful for the commandline interface lateron.
Review appreciated. Also have a look at the tests, how wonderful I made the interface to this functionality ( 😄 )!
This commit is contained in:
commit
6fec701144
4 changed files with 140 additions and 0 deletions
39
libimagutil/Cargo.lock
generated
39
libimagutil/Cargo.lock
generated
|
@ -1,4 +1,43 @@
|
|||
[root]
|
||||
name = "libimagutil"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"regex 0.1.47 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "0.1.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"aho-corasick 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
|
|
|
@ -2,3 +2,7 @@
|
|||
name = "libimagutil"
|
||||
version = "0.1.0"
|
||||
authors = ["Matthias Beyer <mail@beyermatthias.de>"]
|
||||
|
||||
[dependencies]
|
||||
regex = "0.1.47"
|
||||
|
||||
|
|
94
libimagutil/src/key_value_split.rs
Normal file
94
libimagutil/src/key_value_split.rs
Normal file
|
@ -0,0 +1,94 @@
|
|||
use regex::Regex;
|
||||
|
||||
use std::convert::Into;
|
||||
use std::convert::From;
|
||||
|
||||
use std::option::Option;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct KeyValue<K, V> {
|
||||
k: K,
|
||||
v: V,
|
||||
}
|
||||
|
||||
impl<K, V> KeyValue<K, V> {
|
||||
|
||||
pub fn new(k: K, v: V) -> KeyValue<K, V> {
|
||||
KeyValue { k: k, v: v }
|
||||
}
|
||||
|
||||
pub fn key(&self) -> &K {
|
||||
&self.k
|
||||
}
|
||||
|
||||
pub fn value(&self) -> &V {
|
||||
&self.v
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<K, V> Into<(K, V)> for KeyValue<K, V> {
|
||||
|
||||
fn into(self) -> (K, V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub trait IntoKeyValue<K, V> {
|
||||
fn into_kv(self) -> Option<KeyValue<K, V>>;
|
||||
}
|
||||
|
||||
impl IntoKeyValue<String, String> for String {
|
||||
|
||||
fn into_kv(self) -> Option<KeyValue<String, String>> {
|
||||
let r = "^(?P<KEY>(.*))=((\"(?P<DOUBLE_QVAL>(.*))\")|(\'(?P<SINGLE_QVAL>(.*)))\'|(?P<VAL>[^\'\"](.*)[^\'\"]))$";
|
||||
let regex = Regex::new(r).unwrap();
|
||||
regex.captures(&self[..]).and_then(|cap| {
|
||||
cap.name("KEY")
|
||||
.map(|name| {
|
||||
cap.name("SINGLE_QVAL")
|
||||
.or(cap.name("DOUBLE_QVAL"))
|
||||
.or(cap.name("VAL"))
|
||||
.map(|value| KeyValue::new(String::from(name), String::from(value)))
|
||||
}).unwrap_or(None)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::{KeyValue, IntoKeyValue};
|
||||
|
||||
#[test]
|
||||
fn test_single_quoted() {
|
||||
let s = String::from("foo='bar'").into_kv().unwrap();
|
||||
assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_quoted() {
|
||||
let s = String::from("foo=\"bar\"").into_kv().unwrap();
|
||||
assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_double_and_single_quoted() {
|
||||
assert!(String::from("foo=\"bar\'").into_kv().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_and_double_quoted() {
|
||||
assert!(String::from("foo=\'bar\"").into_kv().is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_not_quoted() {
|
||||
let s = String::from("foo=bar").into_kv().unwrap();
|
||||
assert_eq!(KeyValue::new(String::from("foo"), String::from("bar")), s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1 +1,4 @@
|
|||
extern crate regex;
|
||||
|
||||
pub mod key_value_split;
|
||||
pub mod variants;
|
||||
|
|
Loading…
Reference in a new issue