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
//! Protocol Buffers utilities for [`db`][`crate::db`] module.

use crate::error::Error;
use crate::protos::{Deserialize, Serialize};
use crate::protos::database::{
    AttributeValue as ProtosAttributeValue,
    attribute_value::Value::{
        StringValue as ProtosStringValue,
        Uint64Value as ProtosUint64Value,
    },
};

use super::AttributeValue;

impl Serialize<ProtosAttributeValue> for AttributeValue {
    fn serialize(&self) -> Result<ProtosAttributeValue, Error> {
        let mut value = ProtosAttributeValue::new();
        value.value = match self {
            AttributeValue::String(s) => Some(ProtosStringValue(s.clone())),
            AttributeValue::Uint64(n) => Some(ProtosUint64Value(*n)),
        };
        Ok(value)
    }
}

impl Deserialize<AttributeValue> for ProtosAttributeValue {
    fn deserialize(self) -> Result<AttributeValue, Error> {
        if let Some(value) = self.value {
            match value {
                ProtosStringValue(s) => Ok(AttributeValue::String(s)),
                ProtosUint64Value(n) => Ok(AttributeValue::Uint64(n)),
            }
        } else {
            Err(Error::InvalidData(format!("missing attribute value")))
        }
    }
}

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

    #[test]
    fn attribute_value_string_can_be_serialized_as_attribute_value_message() {
        let input = AttributeValue::String("string".to_string());
        let output = input.serialize().unwrap();
        assert_eq!(
            output.value,
            Some(ProtosStringValue("string".to_string())),
        );
    }

    #[test]
    fn attribute_value_string_can_be_deserialized_from_attribute_value_message() {
        let mut input = ProtosAttributeValue::new();
        input.value = Some(ProtosStringValue("string".to_string()));
        let output = input.deserialize().unwrap();
        assert_eq!(output, AttributeValue::String("string".to_string()));
    }

    #[test]
    fn attribute_value_uint64_can_be_serialized_as_attribute_value_message() {
        let input = AttributeValue::Uint64(0x1234_5678_9ABC_DEF0u64);
        let output = input.serialize().unwrap();
        assert_eq!(
            output.value,
            Some(ProtosUint64Value(0x1234_5678_9ABC_DEF0u64)),
        );
    }

    #[test]
    fn attribute_value_uint64_can_be_deserialized_from_attribute_value_message() {
        let mut input = ProtosAttributeValue::new();
        input.value = Some(ProtosUint64Value(0x1234_5678_9ABC_DEF0u64));
        let output = input.deserialize().unwrap();
        assert_eq!(output, AttributeValue::Uint64(0x1234_5678_9ABC_DEF0u64));
    }

    #[test]
    fn attribute_value_message_without_value_cannot_be_deserialized() {
        assert!(ProtosAttributeValue::new().deserialize().is_err());
    }
}