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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use std::fmt::Display;

#[cfg(feature="writing")]
pub mod writer;
#[cfg(feature="reading")]
pub mod reader;

/// A segment of data used by VarReader and VarWriter to send and receive data over a stream.
/// # Examples
/// ```
/// use send_it::Segment;
///
/// let mut segment = Segment::new();
/// segment.append(Segment::from("Hello, "));
/// segment.append(Segment::from("World!"));
///
/// assert_eq!(segment.to_string(), "Hello, World!");
/// ```
#[derive(Debug, Clone)]
pub struct Segment {
    seg: Vec<u8>
}

impl Segment {
    /// Creates a new Segment.
    pub fn new() -> Self {
        Self {
            seg: Vec::new()
        }
    }

    pub fn to_readable(segments: Vec<Segment>) -> Vec<String> {
        segments.iter().map(|s| s.to_string()).collect::<Vec<String>>()
    }

    /// Appends a Segment to the end of this Segment.
    pub fn append(&mut self, seg: Segment) {
        self.seg.extend(seg.seg);
    }

    pub(crate) fn len(&self) -> usize {
        self.seg.len()
    }

    pub fn to_raw(&self) -> Vec<u8> {
        self.seg.clone()
    }
    
}

impl Default for Segment {
    fn default() -> Self {
        Self::new()
    }
}

impl AsRef<[u8]> for Segment {
    fn as_ref(&self) -> &[u8] {
        &self.seg
    }
}

impl From<&[u8]> for Segment {
    fn from(value: &[u8]) -> Self {
        Self {
            seg: value.to_vec()
        }
    }
}

impl From<Vec<u8>> for Segment {
    fn from(value: Vec<u8>) -> Self {
        Self {
            seg: value
        }
    }
}

impl From<String> for Segment {
    fn from(value: String) -> Self {
        Self {
            seg: value.as_bytes().to_vec()
        }
    }
}

impl Display for Segment {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", String::from_utf8_lossy(&self.seg))
    }
}

mod tests {

    #[test]
    fn test_writer() {
        // Create a new VarWriter
        let mut writer = crate::writer::VarWriter::new();

        // Add some sample data
        writer.add_string("Hello, ");
        writer.add_string("World!");

        // Use any Write implementor as your stream (i.e. TcpStream)
        let mut stream: Vec<u8> = Vec::new();

        // encode the data and send it over the stream
        writer.send(&mut stream).expect("Failed to send data");
    }

    #[test]
    fn test_reader() {
        // Create a sample stream, this is the output from the above test_writer test
        let stream: Vec<u8> = vec![21, 7, 0, 0, 0, 72, 101, 108, 108, 111, 44, 32, 6, 0, 0, 0, 87, 111, 114, 108, 100, 33];
        // turn the vector into a slice as Vec does not implement Read
        let mut fake_stream = stream.as_slice();

        // create a new VarReader
        let mut reader = crate::reader::VarReader::new(&mut fake_stream);

        // read the data from the stream
        let data = reader.read_data().unwrap();
        assert_eq!(data[0].to_string(), "Hello, ");
        assert_eq!(data[1].to_string(), "World!");
    }

    #[test]
    fn both_test() {
        // Create a new VarWriter
        let mut writer = crate::writer::VarWriter::new();

        // Add some sample data
        writer.add_string("Hello, ");
        writer.add_string("World!");

        // Use any Write implementor as your stream (i.e. TcpStream)
        let mut stream: Vec<u8> = Vec::new();

        // encode the data and send it over the stream
        writer.send(&mut stream).expect("Failed to send data");

        // turn the vector into a slice as Vec does not implement Read
        let mut fake_stream = stream.as_slice();

        // create a new VarReader
        let mut reader = crate::reader::VarReader::new(&mut fake_stream);

        // read the data from the stream
        let data = reader.read_data().unwrap();
        assert_eq!(data[0].to_string(), "Hello, ");
        assert_eq!(data[1].to_string(), "World!");
    }
}