use columnar::{Columnar, ContainerBytes, Borrow};
#[derive(Columnar)]
enum Group<T> {
Solo(T),
Team(Vec<T>),
}
fn main() {
let mut roster = Vec::new();
roster.push(Group::Solo(
("Alice".to_string(), 20u64)
));
roster.push(Group::Team(vec![
("Bob".to_string(), 21),
("Carol".to_string(), 22),
]));
let mut columns = Columnar::as_columns(roster.iter());
use columnar::Index;
for (col, row) in columns.into_index_iter().zip(roster) {
match (col, row) {
(GroupReference::Solo(p0), Group::Solo(p1)) => {
assert_eq!(p0.0, p1.0.as_bytes());
assert_eq!(p0.1, &p1.1);
},
(GroupReference::Team(p0s), Group::Team(p1s)) => {
assert_eq!(p0s.len(), p1s.len());
for (p0, p1) in p0s.into_iter().zip(p1s) {
assert_eq!(p0.0, p1.0.as_bytes());
assert_eq!(p0.1, &p1.1);
}
},
_ => { panic!("Variant mismatch"); }
}
}
use columnar::Push;
for index in 0 .. 1024 {
columns.push(&Group::Team(vec![
(format_args!("Brain{}", index), index),
(format_args!("Brawn{}", index), index),
]));
}
use columnar::AsBytes;
assert_eq!(columns.borrow().as_bytes().count(), 9);
for (align, bytes) in columns.borrow().as_bytes() {
println!("align: {:?}, bytes.len(): {:?}", align, bytes.len());
}
fn round_trip<'a, C: ContainerBytes>(container: &'a C) -> C::Borrowed<'a> {
let borrow = container.borrow();
let mut bytes_iter = borrow.as_bytes().map(|(_, bytes)| bytes);
columnar::FromBytes::from_bytes(&mut bytes_iter)
}
let borrowed = round_trip(&columns);
let solo_values: &[u64] = borrowed.Solo.1;
let team_values: &[u64] = borrowed.Team.values.1;
let total = solo_values.iter().sum::<u64>() + team_values.iter().sum::<u64>();
println!("Present values summed: {:?}", total);
}
#[cfg(test)]
mod test {
use columnar::Columnar;
#[derive(Columnar, Debug)]
struct Test1<T: Copy> where T: Clone {
foo: Vec<T>,
bar: i16,
}
#[derive(Columnar, Debug)]
#[columnar(derive(Ord, PartialOrd, PartialEq, Eq))]
struct Test2<T: Copy> (Vec<T>, i16) where T: Clone;
#[derive(Columnar, Debug)]
#[columnar(derive(Ord, PartialOrd, PartialEq, Eq))]
pub enum Test3<T> {
Foo(Vec<T>, u8),
Bar(i16),
Void,
}
#[derive(Columnar, Debug, Copy, Clone)]
pub enum Test4 {
Foo,
Bar,
}
#[derive(Columnar, Debug, Copy, Clone)]
struct Test5;
#[derive(Columnar, Debug)]
#[columnar(derive(Ord, PartialOrd, PartialEq, Eq))]
struct Test6 {
bar: i16,
}
#[test]
fn should_be_ord_eq() {
fn is_ord_eq<T: Ord + PartialOrd + PartialEq + Eq>() {}
is_ord_eq::<Test6Reference<i16>>();
is_ord_eq::<Test6Reference<&i16>>();
is_ord_eq::<Test3Reference<u8, u8, u8>>();
}
#[test]
fn round_trip() {
use columnar::Index;
let test1s = vec![
Test1 { foo: vec![1, 2, 3], bar: 4 },
Test1 { foo: vec![5, 6, 7], bar: 8 },
];
let test1c = columnar::Columnar::as_columns(test1s.iter());
for (a, b) in test1s.into_iter().zip((&test1c).into_index_iter()) {
assert_eq!(a.foo.len(), b.foo.len());
assert_eq!(a.bar, *b.bar);
}
let test3s = vec![
Test3::Foo(vec![1, 2, 3], 4),
Test3::Bar(4),
];
let test3c = columnar::Columnar::as_columns(test3s.iter());
println!("{:?}", test3c);
let iterc = (&test3c).into_index_iter();
for (a, b) in test3s.into_iter().zip(iterc) {
match (a, &b) {
(Test3::Foo(a, b), Test3Reference::Foo((c, d))) => {
assert_eq!(a.len(), c.len());
assert_eq!(b, **d);
},
(Test3::Bar(a), Test3Reference::Bar(b)) => {
assert_eq!(a, **b);
},
_ => { panic!("Variant mismatch"); }
}
}
}
#[derive(Columnar, Debug)]
pub enum Test7 {
Click { x: u64, y: u64 },
Scroll(i64),
Idle,
}
#[test]
fn named_enum_fields() {
use columnar::{Borrow, Index, Len, Push, Columnar};
let items = vec![
Test7::Click { x: 10, y: 20 },
Test7::Scroll(-5),
Test7::Idle,
Test7::Click { x: 30, y: 40 },
];
let columns = Columnar::as_columns(items.iter());
assert_eq!(columns.len(), 4);
match (&columns).get(0) {
Test7Reference::Click((x, y)) => { assert_eq!(x, 10); assert_eq!(y, 20); },
_ => panic!("expected Click"),
}
match (&columns).get(1) {
Test7Reference::Scroll(d) => { assert_eq!(d, -5); },
_ => panic!("expected Scroll"),
}
match (&columns).get(2) {
Test7Reference::Idle(_) => {},
_ => panic!("expected Idle"),
}
match (&columns).get(3) {
Test7Reference::Click((x, y)) => { assert_eq!(x, 30); assert_eq!(y, 40); },
_ => panic!("expected Click"),
}
let borrowed = columns.borrow();
let owned: Test7 = Columnar::into_owned(borrowed.get(0));
match owned {
Test7::Click { x, y } => { assert_eq!(x, 10); assert_eq!(y, 20); },
_ => panic!("expected Click"),
}
let mut columns2: columnar::ContainerOf<Test7> = Default::default();
columns2.push(&Test7::Click { x: 99, y: 100 });
match (&columns2).get(0) {
Test7Reference::Click((x, y)) => { assert_eq!(x, 99); assert_eq!(y, 100); },
_ => panic!("expected Click"),
}
}
#[test]
fn iterators_formatters() {
use columnar::Push;
let mut columns = <((), Vec<usize>) as Columnar>::Container::default();
columns.push(((), 0 .. 10));
let mut columns = <((), String) as Columnar>::Container::default();
columns.push(((), format_args!("{:?}", 10)));
}
#[test]
fn extend_from_self_enum() {
use columnar::{Borrow, Container, Index, Len, Push};
let mut columns = <Test3<u8> as Columnar>::Container::default();
columns.push(Test3::<u8>::Foo(vec![1, 2], 10));
columns.push(Test3::<u8>::Bar(20));
columns.push(Test3::<u8>::Foo(vec![3], 30));
columns.push(Test3::<u8>::Void);
let mut dest = <Test3<u8> as Columnar>::Container::default();
dest.extend_from_self(columns.borrow(), 1..3);
assert_eq!(dest.len(), 2);
match dest.borrow().get(0) {
Test3Reference::Bar(x) => assert_eq!(*x, 20),
other => panic!("Expected Bar, got {:?}", other),
}
match dest.borrow().get(1) {
Test3Reference::Foo((v, x)) => {
assert_eq!(v.len(), 1);
assert_eq!(*x, 30);
},
other => panic!("Expected Foo, got {:?}", other),
}
let mut tags = <Test4 as Columnar>::Container::default();
tags.push(Test4::Foo);
tags.push(Test4::Bar);
tags.push(Test4::Foo);
let mut dest_tags = <Test4 as Columnar>::Container::default();
dest_tags.extend_from_self(tags.borrow(), 0..3);
assert_eq!(dest_tags.len(), 3);
assert!(matches!(dest_tags.borrow().get(0), Test4::Foo));
assert!(matches!(dest_tags.borrow().get(1), Test4::Bar));
assert!(matches!(dest_tags.borrow().get(2), Test4::Foo));
}
#[derive(Columnar, Debug, Copy, Clone)]
enum Strange { None, Some }
#[derive(Columnar, Debug, Clone)]
struct BoxedStr {
value: Box<str>,
}
}