Function encode

Source
pub fn encode<T: VarInt>(value: T, buf: &mut [u8]) -> Result<usize, Error>
Expand description

Encodes arbitrary VarInt type to varint format

Returns the number of bytes written

§Parameters

  • value - The value to encode
  • buf - Output buffer

§Errors

Returns Error::BufferTooSmall if the buffer is too small

Examples found in repository?
examples/benchmark.rs (line 114)
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/iter_example.rs (line 33)
15fn main() {
16    println!("=== Iterator-based API Example ===\n");
17    
18    // 1. Encoding a single value using VarIntBytesIter iterator
19    println!("1. Encoding a single value using VarIntBytesIter iterator:");
20    let value = 16384u64;
21    
22    println!("  Encoding value: {}", value);
23    println!("  Expected bytes: {}", tiny_varint::varint_size(value));
24    
25    print!("  Encoded bytes: [ ");
26    for byte in bytes_of(value) {
27        print!("{:#04x} ", byte);
28    }
29    println!("]");
30    
31    // Manually verify the result
32    let mut manual_buf = [0u8; 10];
33    let manual_size = tiny_varint::encode(value, &mut manual_buf).unwrap();
34    
35    print!("  Verification bytes: [ ");
36    for i in 0..manual_size {
37        print!("{:#04x} ", manual_buf[i]);
38    }
39    println!("]\n");
40    
41    // 2. Decoding using VarIntValuesIter iterator
42    println!("2. Decoding using VarIntValuesIter iterator:");
43    
44    // Create a buffer containing multiple varints
45    let values = [0u64, 1, 127, 128, 16383, 16384, 2097151];
46    let mut buffer = [0u8; 100];
47    
48    let mut encoder = VarIntEncoder::new(&mut buffer);
49    let bytes_written = encoder.write_batch(&values).unwrap();
50    
51    print!("  Encoded bytes: [ ");
52    for i in 0..bytes_written {
53        print!("{:#04x} ", buffer[i]);
54    }
55    println!("]");
56    
57    println!("  Decoded values:");
58    for result in values_from::<u64>(&buffer[..bytes_written]) {
59        match result {
60            Ok(value) => println!("    - {}", value),
61            Err(e) => println!("    - Error: {:?}", e),
62        }
63    }
64    
65    // 3. Processing zigzag-encoded values without intermediate buffers
66    println!("\n3. Processing zigzag-encoded signed values:");
67    
68    let signed_values = [-100i32, -50, -10, -1, 0, 1, 10, 50, 100];
69    println!("  Original values: {:?}", signed_values);
70    
71    // Create a zigzag-encoded byte iterator for each value
72    for &value in &signed_values {
73        // First apply zigzag encoding
74        let mut buf = [0u8; 10];
75        let size = encode_zigzag(value, &mut buf).unwrap();
76        
77        print!("  ZigZag encoding for {}: [ ", value);
78        for i in 0..size {
79            print!("{:#04x} ", buf[i]);
80        }
81        println!("]");
82    }
83    
84    // 4. Combining iterators with encoders/decoders
85    println!("\n4. Combining iterators with encoders/decoders in stream processing:");
86    
87    // Simulate a simple data processing pipeline
88    println!("  Data processing pipeline:");
89    println!("    1. Generate raw data");
90    println!("    2. Encode using iterator-based methods");
91    println!("    3. Process encoded bytes");
92    println!("    4. Decode using iterator-based methods");
93    
94    // Raw data
95    let source_data = [42u64, 314, 2718, 31415];
96    println!("\n  Raw data: {:?}", source_data);
97    
98    // Encode and collect
99    let mut encoded_bytes = Vec::new();
100    
101    for &value in &source_data {
102        let encoder = bytes_of(value);
103        println!("  Encoding {} -> {} bytes", value, encoder.size());
104        
105        // Add bytes to our buffer
106        for byte in encoder {
107            encoded_bytes.push(byte);
108        }
109    }
110    
111    print!("  All encoded bytes: [ ");
112    for byte in &encoded_bytes {
113        print!("{:#04x} ", byte);
114    }
115    println!("]");
116    
117    // Decode bytes
118    println!("\n  Decoding results:");
119    let decoder = values_from::<u64>(&encoded_bytes);
120    
121    let mut i = 0;
122    for result in decoder {
123        match result {
124            Ok(value) => {
125                println!("    Original: {}, Decoded: {}", source_data[i], value);
126                i += 1;
127            }
128            Err(e) => println!("    Error: {:?}", e),
129        }
130    }
131    
132    println!("\n=== Example Complete ===");
133}
examples/basic_usage.rs (line 25)
16fn main() {
17    println!("=== tiny-varint Basic Example (no-alloc version) ===\n");
18    
19    // 1. Single unsigned integer encoding/decoding
20    println!("1. Encoding and decoding single unsigned integers:");
21    let values = [0u64, 127, 128, 16383, 16384, 2097151];
22    
23    for &value in &values {
24        let mut buf = [0u8; 10];
25        let bytes_written = encode(value, &mut buf).unwrap();
26        
27        print!("  Value {} encoded as {} bytes: [ ", value, bytes_written);
28        for i in 0..bytes_written {
29            print!("{:#04x} ", buf[i]);
30        }
31        println!("]");
32        
33        let (decoded, bytes_read) = decode::<u64>(&buf).unwrap();
34        println!("  Decoded: {} (read {} bytes)", decoded, bytes_read);
35        println!();
36    }
37    
38    // 2. Signed integer zigzag encoding/decoding
39    println!("\n2. ZigZag encoding and decoding of signed integers:");
40    let signed_values = [0i32, 1, -1, 2, -2, 127, -127, 128, -128];
41    
42    for &value in &signed_values {
43        let mut buf = [0u8; 10];
44        let bytes_written = encode_zigzag(value, &mut buf).unwrap();
45        
46        print!("  Value {} encoded as {} bytes: [ ", value, bytes_written);
47        for i in 0..bytes_written {
48            print!("{:#04x} ", buf[i]);
49        }
50        println!("]");
51        
52        let (decoded, bytes_read) = decode_zigzag::<i32>(&buf).unwrap();
53        println!("  Decoded: {} (read {} bytes)", decoded, bytes_read);
54        println!();
55    }
56    
57    // 3. Batch processing using VarIntEncoder/VarIntDecoder
58    println!("\n3. Batch processing using VarIntEncoder/VarIntDecoder:");
59    let batch_values = [1u64, 127, 128, 16383, 16384, 2097151];
60    let mut buffer = [0u8; 100];
61    
62    // Using encoder
63    let mut encoder = VarIntEncoder::new(&mut buffer);
64    let bytes_written = encoder.write_batch(&batch_values).unwrap();
65    
66    println!("  Encoded {} values using {} bytes", batch_values.len(), bytes_written);
67    
68    print!("  Encoded bytes: [ ");
69    for i in 0..bytes_written {
70        print!("{:#04x} ", buffer[i]);
71    }
72    println!("]");
73    
74    // Using decoder
75    let mut decoder = VarIntDecoder::new(&buffer[..bytes_written]);
76    let mut decoded = [0u64; 6];
77    let count = decoder.read_batch(&mut decoded).unwrap();
78    
79    print!("  Decoded values: [ ");
80    for i in 0..count {
81        print!("{} ", decoded[i]);
82    }
83    println!("]");
84    println!("  Read {} bytes in total", decoder.position());
85    
86    // 4. Using different integer types
87    println!("\n4. Using different integer types:");
88    
89    // Using u64 type
90    let value = 16384u64;
91    let mut buf = [0u8; 10];
92    let size = encode(value, &mut buf).unwrap();
93    
94    print!("  u64 value {} encoded as {} bytes: [ ", value, size);
95    for i in 0..size {
96        print!("{:#04x} ", buf[i]);
97    }
98    println!("]");
99    
100    let (decoded, bytes_read) = decode::<u64>(&buf).unwrap();
101    println!("  Decoded: {} (read {} bytes)", decoded, bytes_read);
102    
103    // Using u32 type
104    let u32_value = 42u32;
105    let mut buf = [0u8; 10];
106    let size = encode(u32_value, &mut buf).unwrap();
107    
108    print!("  u32 value {} encoded as {} bytes: [ ", u32_value, size);
109    for i in 0..size {
110        print!("{:#04x} ", buf[i]);
111    }
112    println!("]");
113    
114    let (decoded, bytes_read) = decode::<u32>(&buf).unwrap();
115    println!("  Decoded: {} (read {} bytes)", decoded, bytes_read);
116    
117    // Using i16 type
118    let i16_value = -256i16;
119    let size = encode(i16_value, &mut buf).unwrap();
120    
121    print!("  i16 value {} encoded as {} bytes: [ ", i16_value, size);
122    for i in 0..size {
123        print!("{:#04x} ", buf[i]);
124    }
125    println!("]");
126    
127    let (decoded, bytes_read) = decode::<i16>(&buf).unwrap();
128    println!("  Decoded: {} (read {} bytes)", decoded, bytes_read);
129    
130    // 5. Error handling
131    println!("\n5. Error handling:");
132    let large_value: u64 = 0xFFFFFFFFFFFFFFFF; // Requires 10 bytes
133    let mut small_buf = [0u8; 5];
134    
135    match encode(large_value, &mut small_buf) {
136        Ok(_) => println!("  Encoding successful (should not reach here)"),
137        Err(Error::BufferTooSmall { needed, actual }) => {
138            println!("  Buffer too small: needed {} bytes, but only had {} bytes", needed, actual);
139        }
140        Err(e) => println!("  Error occurred: {:?}", e),
141    }
142    
143    // Create an incomplete varint - flag bit is 1 but no following bytes
144    let incomplete_buf = [0x80];
145    
146    match decode::<u64>(&incomplete_buf) {
147        Ok(_) => println!("  Decoding successful (should not reach here)"),
148        Err(Error::InputTooShort) => {
149            println!("  Input too short: high bit is 1 indicating more bytes follow, but data ended");
150        }
151        Err(e) => println!("  Error occurred: {:?}", e),
152    }
153    
154    println!("\n=== Example Complete ===");
155}
examples/value_types.rs (line 66)
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}