VarintValue

Enum VarintValue 

Source
pub enum VarintValue {
    U8(u8),
    U16(u16),
    U32(u32),
    U64(u64),
    U128(u128),
    I8(i8),
    I16(i16),
    I32(i32),
    I64(i64),
    I128(i128),
}
Expand description

Enum representing different integer types that can be encoded as varints. Each variant wraps a specific Rust integer type.

Variants§

§

U8(u8)

Unsigned 8-bit integer

§

U16(u16)

Unsigned 16-bit integer

§

U32(u32)

Unsigned 32-bit integer

§

U64(u64)

Unsigned 64-bit integer

§

U128(u128)

Unsigned 128-bit integer

§

I8(i8)

Signed 8-bit integer

§

I16(i16)

Signed 16-bit integer

§

I32(i32)

Signed 32-bit integer

§

I64(i64)

Signed 64-bit integer

§

I128(i128)

Signed 128-bit integer

Implementations§

Source§

impl VarintValue

Source

pub fn get_type_id(&self) -> u8

Returns the type identifier byte for this value

Examples found in repository?
examples/benchmark.rs (line 65)
41fn main() {
42    println!("VarintValue Performance Test");
43    println!("===========================\n");
44    
45    // Test parameters
46    const ITERATIONS: usize = 1_000_000;
47    
48    // Prepare test data and buffer
49    let test_values = [
50        varint!(u8: 127),
51        varint!(u16: 16383),
52        varint!(u32: 1000000),
53        varint!(i8: -42),
54        varint!(i16: -1000),
55        varint!(i32: -100000),
56        varint!(u64: 1_000_000_000_000),
57    ];
58    
59    let mut buffer = [0u8; 20];
60    
61    // 1. Test type ID calculation performance
62    let mut benchmark = Benchmark::new("Type ID calculation", ITERATIONS);
63    benchmark.run(|| {
64        for value in &test_values {
65            let _ = value.get_type_id();
66        }
67    });
68    benchmark.report();
69    
70    // 2. Test serialization size calculation performance
71    let mut benchmark = Benchmark::new("Serialization size calculation", ITERATIONS);
72    benchmark.run(|| {
73        for value in &test_values {
74            let _ = value.serialized_size();
75        }
76    });
77    benchmark.report();
78    
79    // 3. Test serialization performance
80    let mut benchmark = Benchmark::new("VarintValue serialization", ITERATIONS / 10);
81    benchmark.run(|| {
82        for value in &test_values {
83            let _ = value.to_bytes(&mut buffer);
84        }
85    });
86    benchmark.report();
87    
88    // Prepare deserialization test
89    let mut encoded_values = Vec::new();
90    let mut positions = Vec::new();
91    let mut pos = 0;
92    
93    for value in &test_values {
94        let bytes_written = value.to_bytes(&mut buffer[..]).unwrap();
95        encoded_values.extend_from_slice(&buffer[..bytes_written]);
96        positions.push((pos, bytes_written));
97        pos += bytes_written;
98    }
99    
100    // 4. Test deserialization performance
101    let mut benchmark = Benchmark::new("VarintValue deserialization", ITERATIONS / 10);
102    benchmark.run(|| {
103        for (start, len) in &positions {
104            let _ = VarintValue::from_bytes(&encoded_values[*start..*start + *len]);
105        }
106    });
107    benchmark.report();
108    
109    // 5. Compare with regular varint encoding (without type information)
110    let u32_values = [127u32, 16383, 1000000];
111    let mut benchmark = Benchmark::new("Regular u32 varint encoding", ITERATIONS);
112    benchmark.run(|| {
113        for value in &u32_values {
114            let _ = encode(*value, &mut buffer);
115        }
116    });
117    benchmark.report();
118    
119    // 6. Compare with regular varint decoding (without type information)
120    let mut u32_encoded = Vec::new();
121    let mut u32_positions = Vec::new();
122    let mut pos = 0;
123    
124    for value in &u32_values {
125        let bytes_written = encode(*value, &mut buffer).unwrap();
126        u32_encoded.extend_from_slice(&buffer[..bytes_written]);
127        u32_positions.push((pos, bytes_written));
128        pos += bytes_written;
129    }
130    
131    let mut benchmark = Benchmark::new("Regular u32 varint decoding", ITERATIONS);
132    benchmark.run(|| {
133        for (start, len) in &u32_positions {
134            let _ = decode::<u32>(&u32_encoded[*start..*start + *len]);
135        }
136    });
137    benchmark.report();
138    
139    println!("\nPerformance Summary:");
140    println!("1. VarintValue type information introduces some performance overhead");
141    println!("2. Optimizations (special zero handling, avoiding temporary buffers, etc.) effectively improve performance");
142    println!("3. For scenarios requiring mixed types, the performance cost is acceptable");
143}
Source

pub fn serialized_size(&self) -> usize

Returns the number of bytes needed to serialize this value

Examples found in repository?
examples/benchmark.rs (line 74)
41fn main() {
42    println!("VarintValue Performance Test");
43    println!("===========================\n");
44    
45    // Test parameters
46    const ITERATIONS: usize = 1_000_000;
47    
48    // Prepare test data and buffer
49    let test_values = [
50        varint!(u8: 127),
51        varint!(u16: 16383),
52        varint!(u32: 1000000),
53        varint!(i8: -42),
54        varint!(i16: -1000),
55        varint!(i32: -100000),
56        varint!(u64: 1_000_000_000_000),
57    ];
58    
59    let mut buffer = [0u8; 20];
60    
61    // 1. Test type ID calculation performance
62    let mut benchmark = Benchmark::new("Type ID calculation", ITERATIONS);
63    benchmark.run(|| {
64        for value in &test_values {
65            let _ = value.get_type_id();
66        }
67    });
68    benchmark.report();
69    
70    // 2. Test serialization size calculation performance
71    let mut benchmark = Benchmark::new("Serialization size calculation", ITERATIONS);
72    benchmark.run(|| {
73        for value in &test_values {
74            let _ = value.serialized_size();
75        }
76    });
77    benchmark.report();
78    
79    // 3. Test serialization performance
80    let mut benchmark = Benchmark::new("VarintValue serialization", ITERATIONS / 10);
81    benchmark.run(|| {
82        for value in &test_values {
83            let _ = value.to_bytes(&mut buffer);
84        }
85    });
86    benchmark.report();
87    
88    // Prepare deserialization test
89    let mut encoded_values = Vec::new();
90    let mut positions = Vec::new();
91    let mut pos = 0;
92    
93    for value in &test_values {
94        let bytes_written = value.to_bytes(&mut buffer[..]).unwrap();
95        encoded_values.extend_from_slice(&buffer[..bytes_written]);
96        positions.push((pos, bytes_written));
97        pos += bytes_written;
98    }
99    
100    // 4. Test deserialization performance
101    let mut benchmark = Benchmark::new("VarintValue deserialization", ITERATIONS / 10);
102    benchmark.run(|| {
103        for (start, len) in &positions {
104            let _ = VarintValue::from_bytes(&encoded_values[*start..*start + *len]);
105        }
106    });
107    benchmark.report();
108    
109    // 5. Compare with regular varint encoding (without type information)
110    let u32_values = [127u32, 16383, 1000000];
111    let mut benchmark = Benchmark::new("Regular u32 varint encoding", ITERATIONS);
112    benchmark.run(|| {
113        for value in &u32_values {
114            let _ = encode(*value, &mut buffer);
115        }
116    });
117    benchmark.report();
118    
119    // 6. Compare with regular varint decoding (without type information)
120    let mut u32_encoded = Vec::new();
121    let mut u32_positions = Vec::new();
122    let mut pos = 0;
123    
124    for value in &u32_values {
125        let bytes_written = encode(*value, &mut buffer).unwrap();
126        u32_encoded.extend_from_slice(&buffer[..bytes_written]);
127        u32_positions.push((pos, bytes_written));
128        pos += bytes_written;
129    }
130    
131    let mut benchmark = Benchmark::new("Regular u32 varint decoding", ITERATIONS);
132    benchmark.run(|| {
133        for (start, len) in &u32_positions {
134            let _ = decode::<u32>(&u32_encoded[*start..*start + *len]);
135        }
136    });
137    benchmark.report();
138    
139    println!("\nPerformance Summary:");
140    println!("1. VarintValue type information introduces some performance overhead");
141    println!("2. Optimizations (special zero handling, avoiding temporary buffers, etc.) effectively improve performance");
142    println!("3. For scenarios requiring mixed types, the performance cost is acceptable");
143}
More examples
Hide additional examples
examples/value_types.rs (line 107)
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}
Source

pub fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, Error>

Serializes the value into a byte buffer.

The first byte contains the type identifier, followed by the encoded integer value. Unsigned integers use standard varint encoding, while signed integers use zigzag encoding.

§Arguments
  • buffer - The buffer to write into
§Returns
  • Ok(size) - The number of bytes written
  • Err(...) - If encoding fails or buffer is too small
Examples found in repository?
examples/benchmark.rs (line 83)
41fn main() {
42    println!("VarintValue Performance Test");
43    println!("===========================\n");
44    
45    // Test parameters
46    const ITERATIONS: usize = 1_000_000;
47    
48    // Prepare test data and buffer
49    let test_values = [
50        varint!(u8: 127),
51        varint!(u16: 16383),
52        varint!(u32: 1000000),
53        varint!(i8: -42),
54        varint!(i16: -1000),
55        varint!(i32: -100000),
56        varint!(u64: 1_000_000_000_000),
57    ];
58    
59    let mut buffer = [0u8; 20];
60    
61    // 1. Test type ID calculation performance
62    let mut benchmark = Benchmark::new("Type ID calculation", ITERATIONS);
63    benchmark.run(|| {
64        for value in &test_values {
65            let _ = value.get_type_id();
66        }
67    });
68    benchmark.report();
69    
70    // 2. Test serialization size calculation performance
71    let mut benchmark = Benchmark::new("Serialization size calculation", ITERATIONS);
72    benchmark.run(|| {
73        for value in &test_values {
74            let _ = value.serialized_size();
75        }
76    });
77    benchmark.report();
78    
79    // 3. Test serialization performance
80    let mut benchmark = Benchmark::new("VarintValue serialization", ITERATIONS / 10);
81    benchmark.run(|| {
82        for value in &test_values {
83            let _ = value.to_bytes(&mut buffer);
84        }
85    });
86    benchmark.report();
87    
88    // Prepare deserialization test
89    let mut encoded_values = Vec::new();
90    let mut positions = Vec::new();
91    let mut pos = 0;
92    
93    for value in &test_values {
94        let bytes_written = value.to_bytes(&mut buffer[..]).unwrap();
95        encoded_values.extend_from_slice(&buffer[..bytes_written]);
96        positions.push((pos, bytes_written));
97        pos += bytes_written;
98    }
99    
100    // 4. Test deserialization performance
101    let mut benchmark = Benchmark::new("VarintValue deserialization", ITERATIONS / 10);
102    benchmark.run(|| {
103        for (start, len) in &positions {
104            let _ = VarintValue::from_bytes(&encoded_values[*start..*start + *len]);
105        }
106    });
107    benchmark.report();
108    
109    // 5. Compare with regular varint encoding (without type information)
110    let u32_values = [127u32, 16383, 1000000];
111    let mut benchmark = Benchmark::new("Regular u32 varint encoding", ITERATIONS);
112    benchmark.run(|| {
113        for value in &u32_values {
114            let _ = encode(*value, &mut buffer);
115        }
116    });
117    benchmark.report();
118    
119    // 6. Compare with regular varint decoding (without type information)
120    let mut u32_encoded = Vec::new();
121    let mut u32_positions = Vec::new();
122    let mut pos = 0;
123    
124    for value in &u32_values {
125        let bytes_written = encode(*value, &mut buffer).unwrap();
126        u32_encoded.extend_from_slice(&buffer[..bytes_written]);
127        u32_positions.push((pos, bytes_written));
128        pos += bytes_written;
129    }
130    
131    let mut benchmark = Benchmark::new("Regular u32 varint decoding", ITERATIONS);
132    benchmark.run(|| {
133        for (start, len) in &u32_positions {
134            let _ = decode::<u32>(&u32_encoded[*start..*start + *len]);
135        }
136    });
137    benchmark.report();
138    
139    println!("\nPerformance Summary:");
140    println!("1. VarintValue type information introduces some performance overhead");
141    println!("2. Optimizations (special zero handling, avoiding temporary buffers, etc.) effectively improve performance");
142    println!("3. For scenarios requiring mixed types, the performance cost is acceptable");
143}
More examples
Hide additional examples
examples/value_types.rs (line 32)
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}
Source

pub fn from_bytes(bytes: &[u8]) -> Result<(Self, usize), Error>

Deserializes a value from a byte buffer.

§Arguments
  • bytes - The byte buffer to read from
§Returns
  • Ok((value, size)) - The deserialized value and number of bytes read
  • Err(...) - If decoding fails
Examples found in repository?
examples/benchmark.rs (line 104)
41fn main() {
42    println!("VarintValue Performance Test");
43    println!("===========================\n");
44    
45    // Test parameters
46    const ITERATIONS: usize = 1_000_000;
47    
48    // Prepare test data and buffer
49    let test_values = [
50        varint!(u8: 127),
51        varint!(u16: 16383),
52        varint!(u32: 1000000),
53        varint!(i8: -42),
54        varint!(i16: -1000),
55        varint!(i32: -100000),
56        varint!(u64: 1_000_000_000_000),
57    ];
58    
59    let mut buffer = [0u8; 20];
60    
61    // 1. Test type ID calculation performance
62    let mut benchmark = Benchmark::new("Type ID calculation", ITERATIONS);
63    benchmark.run(|| {
64        for value in &test_values {
65            let _ = value.get_type_id();
66        }
67    });
68    benchmark.report();
69    
70    // 2. Test serialization size calculation performance
71    let mut benchmark = Benchmark::new("Serialization size calculation", ITERATIONS);
72    benchmark.run(|| {
73        for value in &test_values {
74            let _ = value.serialized_size();
75        }
76    });
77    benchmark.report();
78    
79    // 3. Test serialization performance
80    let mut benchmark = Benchmark::new("VarintValue serialization", ITERATIONS / 10);
81    benchmark.run(|| {
82        for value in &test_values {
83            let _ = value.to_bytes(&mut buffer);
84        }
85    });
86    benchmark.report();
87    
88    // Prepare deserialization test
89    let mut encoded_values = Vec::new();
90    let mut positions = Vec::new();
91    let mut pos = 0;
92    
93    for value in &test_values {
94        let bytes_written = value.to_bytes(&mut buffer[..]).unwrap();
95        encoded_values.extend_from_slice(&buffer[..bytes_written]);
96        positions.push((pos, bytes_written));
97        pos += bytes_written;
98    }
99    
100    // 4. Test deserialization performance
101    let mut benchmark = Benchmark::new("VarintValue deserialization", ITERATIONS / 10);
102    benchmark.run(|| {
103        for (start, len) in &positions {
104            let _ = VarintValue::from_bytes(&encoded_values[*start..*start + *len]);
105        }
106    });
107    benchmark.report();
108    
109    // 5. Compare with regular varint encoding (without type information)
110    let u32_values = [127u32, 16383, 1000000];
111    let mut benchmark = Benchmark::new("Regular u32 varint encoding", ITERATIONS);
112    benchmark.run(|| {
113        for value in &u32_values {
114            let _ = encode(*value, &mut buffer);
115        }
116    });
117    benchmark.report();
118    
119    // 6. Compare with regular varint decoding (without type information)
120    let mut u32_encoded = Vec::new();
121    let mut u32_positions = Vec::new();
122    let mut pos = 0;
123    
124    for value in &u32_values {
125        let bytes_written = encode(*value, &mut buffer).unwrap();
126        u32_encoded.extend_from_slice(&buffer[..bytes_written]);
127        u32_positions.push((pos, bytes_written));
128        pos += bytes_written;
129    }
130    
131    let mut benchmark = Benchmark::new("Regular u32 varint decoding", ITERATIONS);
132    benchmark.run(|| {
133        for (start, len) in &u32_positions {
134            let _ = decode::<u32>(&u32_encoded[*start..*start + *len]);
135        }
136    });
137    benchmark.report();
138    
139    println!("\nPerformance Summary:");
140    println!("1. VarintValue type information introduces some performance overhead");
141    println!("2. Optimizations (special zero handling, avoiding temporary buffers, etc.) effectively improve performance");
142    println!("3. For scenarios requiring mixed types, the performance cost is acceptable");
143}
More examples
Hide additional examples
examples/value_types.rs (line 50)
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}

Trait Implementations§

Source§

impl Clone for VarintValue

Source§

fn clone(&self) -> VarintValue

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for VarintValue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for VarintValue

Source§

fn eq(&self, other: &VarintValue) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Copy for VarintValue

Source§

impl StructuralPartialEq for VarintValue

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.