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
//! # Ether - transfer data through means
//! **Ether** provides traits that abstracts data transmission layer, allowing developers to build applications that can transfer datas online through various means without worrying apis from each mean.
/// A stream transfer protocol.
pub trait StreamTransfer {
    /// Connect to stream. Most implments should do two things here:
    ///
    /// 1. `Connect` to the stream.
    /// 2. Make sure the server / other peer is online and active.
    fn connect(&mut self) -> Result<(), String>;
    /// Try to receive a data packet and remove it from queue.
    fn recv(&mut self) -> Result<Option<Vec<u8>>, String>;
    /// Try to receive a data packet.
    fn peek(&mut self) -> Result<Option<Vec<u8>>, String>;
    /// Send a data packet to the server / other peer.
    fn send(&mut self, data: Vec<u8>) -> Result<(), String>;
}
/// A packet transfer protocol. It is similear to `StreamTransfer` trait but provides a `tag` for transfer index.
pub trait PacketTransfer {
    /// Connect to host. Most implments should make sure the server / other peer is avaliable.
    fn connect(&mut self) -> Result<(), String>;
    /// Try to receive a data packet and remove it.
    fn recv(&mut self, tag: &str) -> Result<Option<Vec<u8>>, String> {
        let ret = self.peek(tag)?;
        self.remove(tag)?;
        Ok(ret)
    }
    /// Try to receive a data packet.
    fn peek(&mut self, tag: &str) -> Result<Option<Vec<u8>>, String>;
    /// Try to send a data packet to the server / other peer.
    fn send(&mut self, tag: &str, data: Vec<u8>) -> Result<(), String>;
    /// Remove the packet from the queue.
    fn remove(&mut self, tag: &str) -> Result<(), String>;
}
/// A data storage protocol.
///
///It is very similear to `PacketTransfer` trait, but implements should guarantee the persistence of the data when implementing `DataStorage`.
pub trait DataStorage {
    /// Connect to host. Most implments should make sure the server / other peer is avaliable.
    fn connect(&mut self) -> Result<(), String>;
    /// Try to download a data packet. Similear to *ftp*'s `GET`.
    fn peek(&mut self, tag: &str) -> Result<Option<Vec<u8>>, String>;
    /// Try to upload a data packet. Similear to *ftp*'s `PUT`.
    fn send(&mut self, tag: &str, data: Vec<u8>) -> Result<(), String>;
    /// Remove the data packet from server.
    fn remove(&mut self, tag: &str) -> Result<(), String>;
}
/// `extends` provides:
///
/// 1. Implementation of `StreamTransfer` for `PacketTransfer` - `StreamTransferOverlay`
/// 2. Implementation of `PacketTransfer` for `DataStorage`
pub mod extends {
    use super::*;
    pub struct StreamTransferOverlay<T: PacketTransfer> {
        packet_transfer: T,
        recv: u128,
        send: u128,
    }
    impl<T: PacketTransfer> StreamTransferOverlay<T> {
        pub fn new(packet_transfer: T) -> Self {
            Self {
                packet_transfer,
                recv: 0,
                send: 0,
            }
        }
    }
    impl<T: PacketTransfer> StreamTransfer for StreamTransferOverlay<T> {
        fn connect(&mut self) -> Result<(), String> {
            self.packet_transfer.connect()
        }
        fn recv(&mut self) -> Result<Option<Vec<u8>>, String> {
            self.recv += 1;
            self.packet_transfer.recv(&(self.recv - 1).to_string())
        }
        fn peek(&mut self) -> Result<Option<Vec<u8>>, String> {
            self.packet_transfer.peek(&self.recv.to_string())
        }
        fn send(&mut self, data: Vec<u8>) -> Result<(), String> {
            self.send += 1;
            self.packet_transfer
                .send(&(self.send - 1).to_string(), data)
        }
    }
    impl<T: DataStorage> PacketTransfer for T {
        fn connect(&mut self) -> Result<(), String> {
            self.connect()
        }
        fn peek(&mut self, tag: &str) -> Result<Option<Vec<u8>>, String> {
            self.peek(tag)
        }
        fn send(&mut self, tag: &str, data: Vec<u8>) -> Result<(), String> {
            self.send(tag, data)
        }
        fn remove(&mut self, tag: &str) -> Result<(), String> {
            self.remove(tag)
        }
    }
}