use std::cmp::Ordering;
enum Fruit {
Apple(i32),
Orange(i32),
}
fn process_fruit(_apple_prices: &[i32], _orange_prices: &[i32]) {
// whatever we do to process fruit, does not matter
}
fn main() {
let mut fruit : Vec<Fruit> = vec![Fruit::Apple(1), Fruit::Apple(2),
Fruit::Orange(4), Fruit::Orange(3),
];
/*
* Sort fruit by some crazy function - let's say we value oranges more
* than apples, so when we compare one to the other, we increase
* the price of oranges by 10.
*/
let fruit_comparator = |x: &Fruit, y: &Fruit| match(x, y) {
(Fruit::Apple(lhs), Fruit::Apple(rhs)) => {
lhs.cmp(rhs)
},
(Fruit::Apple(lhs), Fruit::Orange(rhs)) => {
lhs.cmp(&(*rhs + 10))
},
(Fruit::Orange(lhs), Fruit::Apple(rhs)) => {
(lhs + 10).cmp(rhs)
},
(Fruit::Orange(lhs), Fruit::Orange(rhs)) => {
lhs.cmp(rhs)
},
};
fruit.sort_by(fruit_comparator);
// apples must __only__ contain Fruit::Apple variants
let mut apple_prices : Vec<i32> = vec![];
// oranges must __only__ contain Fruit::Orange variants
let mut orange_prices : Vec<i32> = vec![];
// TODO generate `fruit_grouped` from an existing sorted `fruit`
let fruit_sorted_by_price_grouped : Vec<Vec<Fruit>> = {
let mut groups = Vec::new();
let mut this_group = Vec::new();
for f in fruit {
if this_group.is_empty() || fruit_comparator(&this_group[0], &f) == Ordering::Equal {
this_group.push(f);
} else {
groups.push(this_group);
this_group = vec![f];
}
}
groups
};
for i in fruit_sorted_by_price_grouped {
for j in i {
match j {
Fruit::Apple(price) => {
apple_prices.push(price);
}
Fruit::Orange(price) => {
orange_prices.push(price);
}
};
process_fruit(&apple_prices, &orange_prices);
apple_prices = vec![];
orange_prices = vec![];
}
}
}