-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Lender type for easily iterating over List builders
A simple utility to help with iterating over List builders. Normally you'd use a Range and write a manual for loop to access element builders, but it doesn't work as well with other Iterators. Lender and ZippedLender provide simple utilities to work with both. While they don't support Iterator itself, we can still use `while let` with them which is close enough...
- Loading branch information
1 parent
90821e3
commit af6f589
Showing
3 changed files
with
130 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use crate::gen::capnp_test_capnp::{TestAllTypes, TestEnum}; | ||
use recapn::message::Message; | ||
use recapn::ty::AsReader; | ||
|
||
#[test] | ||
fn test_lender() { | ||
// Lender primarily exists for copying from native types to Cap'n Proto types. Lists are | ||
// especially painful to deal with because it requires using enumerator() and that sucks. | ||
// Lender gives a nicer API that, while it doesn't support `for` syntax, does support | ||
// `while let` which is the next best thing. | ||
|
||
struct Data { | ||
value: i8, | ||
big_value: u64, | ||
enum_value: TestEnum, | ||
} | ||
|
||
let some_data = vec![ | ||
Data { value: 5, big_value: 0, enum_value: TestEnum::Qux }, | ||
Data { value: -1, big_value: 0xFFFFFFFFFFFFF, enum_value: TestEnum::Bar }, | ||
]; | ||
|
||
let mut message = Message::global(); | ||
let mut builder = message.builder().init_struct_root::<TestAllTypes>(); | ||
let mut list = builder.struct_list() | ||
.init(some_data.len() as u32) | ||
.into_lender() | ||
.zip(&some_data); | ||
while let Some((builder, data)) = list.next() { | ||
let mut e = builder.get(); | ||
e.int8_field().set(data.value); | ||
e.u_int64_field().set(data.big_value); | ||
e.enum_field().set(data.enum_value); | ||
} | ||
|
||
let list = builder.as_reader().struct_list().get(); | ||
assert_eq!(list.len(), some_data.len() as u32); | ||
|
||
for (e, data) in list.into_iter().zip(&some_data) { | ||
assert_eq!(e.int8_field(), data.value); | ||
assert_eq!(e.u_int64_field(), data.big_value); | ||
assert_eq!(e.enum_field().unwrap(), data.enum_value); | ||
} | ||
|
||
// Check to make sure other types of ranges work. | ||
let mut list = builder.bool_list().init(6).into_lender_range(2..=3); | ||
while let Some(mut b) = list.next() { | ||
b.set(true); | ||
} | ||
|
||
let list = builder.as_reader().bool_list().get(); | ||
assert_eq!(list.len(), 6); | ||
assert!(list.into_iter().eq([false, false, true, true, false, false].into_iter())); | ||
|
||
// Going into ranges out of bounds yields no elements. | ||
let mut list = builder.u_int8_list().init(3).into_lender_range(4..); | ||
assert!(list.next().is_none()); | ||
} |