1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use std::collections::BTreeMap;
use serde::ser::SerializeMap;
use serde::{Serialize, Serializer};
pub type ArgName = String;
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ArgValue {
Int(i64),
String(String),
}
#[derive(Clone, Default, PartialEq, Eq, Debug)]
pub struct ArgValues(BTreeMap<ArgName, ArgValue>);
impl ArgValues {
#[inline]
pub fn new() -> Self {
ArgValues(BTreeMap::new())
}
#[inline]
pub fn add<N: Into<ArgName>, V: Into<ArgValue>>(&mut self, name: N, value: V) -> &mut Self {
let ArgValues(map) = self;
map.insert(name.into(), value.into());
self
}
}
impl Serialize for ArgValues {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let ArgValues(map) = self;
let mut encoder = serializer.serialize_map(Some(map.len()))?;
for (k, v) in map {
match v {
ArgValue::Int(int_val) => encoder.serialize_entry(k, int_val)?,
ArgValue::String(str_val) => encoder.serialize_entry(k, str_val)?,
}
}
encoder.end()
}
}
#[test]
fn test_args_ser() -> Result<(), Box<dyn std::error::Error>> {
let mut args = ArgValues::new();
args.add("foo".to_string(), ArgValue::String("bar".to_string()));
args.add("boo".to_string(), ArgValue::Int(42));
args.add("zoo".to_string(), ArgValue::Int(-42));
let benc = String::from_utf8(bencode::to_bytes(&args)?)?;
assert_eq!(benc, "d3:booi42e3:foo3:bar3:zooi-42ee");
Ok(())
}
impl From<i64> for ArgValue {
#[inline]
fn from(value: i64) -> Self {
ArgValue::Int(value)
}
}
impl From<String> for ArgValue {
#[inline]
fn from(value: String) -> Self {
ArgValue::String(value)
}
}
impl From<&str> for ArgValue {
#[inline]
fn from(value: &str) -> Self {
ArgValue::String(value.to_string())
}
}
#[test]
fn test_arg_value_conversion() {
fn arg<T: Into<ArgValue>>(v: T) -> ArgValue {
v.into()
}
assert_eq!(arg(42), ArgValue::Int(42));
assert_eq!(arg(-42), ArgValue::Int(-42));
assert_eq!(arg("foo"), ArgValue::String("foo".to_string()));
assert_eq!(arg("bar".to_string()), ArgValue::String("bar".to_string()));
}