value_types/
value_types.rs

1use tiny_varint::{VarintValue, varint, encode};
2
3fn main() {
4    println!("VarintValue Mixed Type Example");
5    println!("=============================\n");
6    
7    // 1. Basic Usage with Different Types
8    println!("1. Basic Usage with Different Types");
9    println!("----------------------------------");
10    
11    // Create values of different types
12    let values = [
13        varint!(u8: 127),
14        varint!(u16: 1000),
15        varint!(u32: 100000),
16        varint!(i8: -42),
17        varint!(i16: -1000),
18        varint!(i32: -100000),
19        varint!(u64: u64::MAX / 2),
20    ];
21    
22    println!("Original values:");
23    for (i, value) in values.iter().enumerate() {
24        println!("  [{}]: {:?}", i, value);
25    }
26    
27    // Serialize each value
28    let mut buffer = [0u8; 100];
29    let mut pos = 0;
30    
31    for value in &values {
32        let bytes_written = value.to_bytes(&mut buffer[pos..]).unwrap();
33        pos += bytes_written;
34    }
35    
36    println!("\nSerialized {} bytes total", pos);
37    println!("Encoded bytes: ");
38    print!("  [ ");
39    for i in 0..pos {
40        print!("{:#04x} ", buffer[i]);
41    }
42    println!("]");
43    
44    // Deserialize values
45    println!("\nDecoded values:");
46    let mut read_pos = 0;
47    let mut index = 0;
48    
49    while read_pos < pos {
50        let (value, bytes_read) = VarintValue::from_bytes(&buffer[read_pos..pos]).unwrap();
51        println!("  [{}]: {:?} (read {} bytes)", index, value, bytes_read);
52        read_pos += bytes_read;
53        index += 1;
54    }
55    
56    // 2. Size Comparison
57    println!("\n2. Size Comparison: Normal vs VarintValue");
58    println!("-----------------------------------------");
59    
60    // With regular encoding
61    let values_regular = [42u32, 1000u32, 100000u32];
62    let mut regular_buffer = [0u8; 100];
63    let mut regular_pos = 0;
64    
65    for &value in &values_regular {
66        let bytes_written = encode(value, &mut regular_buffer[regular_pos..]).unwrap();
67        regular_pos += bytes_written;
68    }
69    
70    // With VarintValue (adds type information)
71    let values_with_type = [
72        varint!(u32: 42),
73        varint!(u32: 1000),
74        varint!(u32: 100000),
75    ];
76    
77    let mut typed_buffer = [0u8; 100];
78    let mut typed_pos = 0;
79    
80    for value in &values_with_type {
81        let bytes_written = value.to_bytes(&mut typed_buffer[typed_pos..]).unwrap();
82        typed_pos += bytes_written;
83    }
84    
85    println!("Same u32 values encoded:");
86    println!("  Regular encoding: {} bytes", regular_pos);
87    println!("  With type info:   {} bytes", typed_pos);
88    println!("  Overhead: {} bytes (+{}%)", 
89        typed_pos - regular_pos, 
90        (typed_pos - regular_pos) * 100 / regular_pos
91    );
92    
93    // 3. Handling Mixed Integers
94    println!("\n3. Handling Mixed Integers in a Stream");
95    println!("-------------------------------------");
96    
97    // Creating a heterogeneous stream of values
98    let mixed_values = [
99        varint!(u8: 42),
100        varint!(i16: -1000),
101        varint!(u32: 100000),
102        varint!(i64: -1000000000),
103    ];
104    
105    // Calculate the total size
106    let total_size: usize = mixed_values.iter()
107        .map(|v| v.serialized_size())
108        .sum();
109    
110    println!("Mixed value sizes:");
111    for (_i, value) in mixed_values.iter().enumerate() {
112        println!("  {:?}: {} bytes", value, value.serialized_size());
113    }
114    println!("Total serialized size: {} bytes", total_size);
115    
116    // 4. Practical Example - Protocol Message
117    println!("\n4. Practical Example - Protocol Message");
118    println!("--------------------------------------");
119    
120    // Simulate a simple protocol message with different field types
121    struct SimpleMessage {
122        message_id: VarintValue,
123        temperature: VarintValue,
124        humidity: VarintValue,
125        data_points: Vec<VarintValue>,
126    }
127    
128    let message = SimpleMessage {
129        message_id: varint!(u32: 1234),
130        temperature: varint!(i16: -5),  // Negative temperature
131        humidity: varint!(u8: 85),      // Small positive value
132        data_points: vec![
133            varint!(i32: -100),         // Negative value
134            varint!(i32: 17),           // Changed to match what's being decoded
135            varint!(i32: 100),          // Positive value
136            varint!(i32: 200),          // Positive value
137        ],
138    };
139    
140    let mut message_buffer = [0u8; 100];
141    let mut message_pos = 0;
142    
143    // Serialize message fields
144    let fields = [
145        &message.message_id, 
146        &message.temperature, 
147        &message.humidity
148    ];
149    
150    for field in &fields {
151        let bytes_written = field.to_bytes(&mut message_buffer[message_pos..]).unwrap();
152        message_pos += bytes_written;
153    }
154    
155    // Serialize length of data_points
156    let data_points_len = varint!(u8: message.data_points.len() as u8);
157    let bytes_written = data_points_len.to_bytes(&mut message_buffer[message_pos..]).unwrap();
158    message_pos += bytes_written;
159    
160    // Serialize data points
161    for point in &message.data_points {
162        let bytes_written = point.to_bytes(&mut message_buffer[message_pos..]).unwrap();
163        message_pos += bytes_written;
164    }
165    
166    println!("Message serialized to {} bytes", message_pos);
167    println!("Message bytes: ");
168    print!("  [ ");
169    for i in 0..message_pos {
170        print!("{:#04x} ", message_buffer[i]);
171    }
172    println!("]");
173    
174    // Deserialize message
175    println!("\nDeserialized message:");
176    
177    let mut read_pos = 0;
178    
179    // Read message ID
180    let (msg_id, bytes_read) = VarintValue::from_bytes(&message_buffer[read_pos..]).unwrap();
181    read_pos += bytes_read;
182    println!("  Message ID: {:?}", msg_id);
183    
184    // Read temperature
185    let (temp, bytes_read) = VarintValue::from_bytes(&message_buffer[read_pos..]).unwrap();
186    read_pos += bytes_read;
187    println!("  Temperature: {:?}", temp);
188    
189    // Read humidity
190    let (humidity, bytes_read) = VarintValue::from_bytes(&message_buffer[read_pos..]).unwrap();
191    read_pos += bytes_read;
192    println!("  Humidity: {:?}", humidity);
193    
194    // Read data points length
195    let (dp_len, bytes_read) = VarintValue::from_bytes(&message_buffer[read_pos..]).unwrap();
196    read_pos += bytes_read;
197    let dp_count = match dp_len {
198        VarintValue::U8(val) => val as usize,
199        _ => panic!("Expected U8 type for data points length"),
200    };
201    println!("  Data points: {}", dp_count);
202    
203    // Read data points
204    for i in 0..dp_count {
205        if read_pos >= message_pos {
206            println!("    Warning: End of buffer reached, some data points may be missing");
207            break;
208        }
209        
210        match VarintValue::from_bytes(&message_buffer[read_pos..message_pos]) {
211            Ok((point, bytes_read)) => {
212                println!("    Point {}: {:?}", i, point);
213                read_pos += bytes_read;
214            },
215            Err(e) => {
216                println!("    Error reading point {}: {:?}", i, e);
217                println!("    Remaining bytes: {} (read position: {}/{})", 
218                    message_pos - read_pos, read_pos, message_pos);
219                // Display remaining bytes in hex to aid debugging
220                print!("    Remaining bytes hex: [");
221                for j in read_pos..message_pos {
222                    print!("{:#04x} ", message_buffer[j]);
223                }
224                println!("]");
225                break;
226            }
227        }
228    }
229    
230    println!("\nExample Complete");
231}