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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::error::Error;

use crate::serialization::state::NodeRef as ProtoNodeRef;
use crate::traits::{Decode, Encode, Proto};

use protobuf::Message as ProtoMessage;

#[derive(Clone, Debug, PartialEq)]
pub struct NodeRef {
    pub node_location: Vec<u8>,
    pub child: Vec<u8>,
}

impl NodeRef {
    pub fn new(location: &Vec<u8>, child: &Vec<u8>) -> NodeRef {
        NodeRef {
            node_location: location.to_vec(),
            child: child.to_vec(),
        }
    }
}

impl Decode for NodeRef {
    fn decode(buffer: &[u8]) -> Result<NodeRef, Box<Error>> {
        let mut proto_node_ref = ProtoNodeRef::new();
        proto_node_ref.merge_from_bytes(buffer)?;
        Ok(NodeRef::new(&proto_node_ref.address, &proto_node_ref.child))
    }
}

impl Proto for NodeRef {
    type ProtoType = ProtoNodeRef;
    fn to_proto(&self) -> Result<Self::ProtoType, Box<Error>> {
        let mut proto_node_ref = Self::ProtoType::new();
        proto_node_ref.set_address(self.node_location.clone());
        proto_node_ref.set_child(self.child.clone());
        Ok(proto_node_ref)
    }

    fn from_proto(_prototype: &Self::ProtoType) -> Result<Self, Box<Error>> {
        unimplemented!()
    }
}

impl Encode for NodeRef {
    fn encode(&self) -> Result<Vec<u8>, Box<Error>> {
        let proto_node_ref = self.to_proto()?;
        Ok(proto_node_ref.write_to_bytes()?)
    }
}

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

    #[test]
    fn it_makes_a_node_ref() {
        let addr = vec![109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let child = vec![137, 28, 167, 193, 135, 226, 96, 56, 197, 123];
        let node_ref = NodeRef::new(&addr, &child);
        assert_eq!(node_ref.node_location, addr);
        assert_eq!(node_ref.child, child);
    }

    #[test]
    fn it_makes_a_node_ref_from_inode_ref() {
        let addr_slice = vec![109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let child = vec![137, 28, 167, 193, 135, 226, 96, 56, 197, 123];
        let mut inode_ref = ProtoNodeRef::new();
        inode_ref.set_address(addr_slice);
        inode_ref.set_child(child);
        let encoded = inode_ref.write_to_bytes().unwrap();

        let node_ref: NodeRef = NodeRef::decode(&encoded).unwrap();
        assert_eq!(
            node_ref.node_location,
            [109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        );
        assert_eq!(
            node_ref.child,
            vec![137, 28, 167, 193, 135, 226, 96, 56, 197, 123]
        );
    }

    #[test]
    fn it_encodes_like_javascript_for_non_zero() {
        let addr_slice = vec![109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let child = vec![
            137, 28, 167, 193, 135, 226, 96, 56, 197, 123, 221, 237, 249, 5, 134, 194, 38, 184,
            100, 131, 41, 152, 47, 186, 185, 70, 18, 162, 105, 115, 14, 42,
        ];
        let node_ref = NodeRef::new(&addr_slice, &child);
        let encoding = node_ref.encode().unwrap();
        let javascript_encoding = vec![
            10, 20, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 32, 137, 28,
            167, 193, 135, 226, 96, 56, 197, 123, 221, 237, 249, 5, 134, 194, 38, 184, 100, 131,
            41, 152, 47, 186, 185, 70, 18, 162, 105, 115, 14, 42,
        ];

        assert_eq!(encoding, javascript_encoding);
    }

    #[test]
    fn it_encodes_like_javascript_for_zero() {
        let addr_slice = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let child = vec![
            0, 28, 0, 193, 0, 226, 0, 56, 0, 123, 0, 237, 0, 5, 0, 194, 0, 184, 0, 131, 0, 152, 0,
            186, 0, 70, 0, 162, 0, 115, 0, 42,
        ];
        let node_ref = NodeRef::new(&addr_slice, &child);
        let encoding = node_ref.encode().unwrap();
        let javascript_encoding = vec![
            10, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 32, 0, 28, 0,
            193, 0, 226, 0, 56, 0, 123, 0, 237, 0, 5, 0, 194, 0, 184, 0, 131, 0, 152, 0, 186, 0,
            70, 0, 162, 0, 115, 0, 42,
        ];

        assert_eq!(encoding, javascript_encoding);
    }
}