Skip to main content

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 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Copy for VarintValue

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 (const: unstable) · 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 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.