1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
use std::sync::mpsc::{Receiver, RecvError};
use super::super::thread_messages::UiToHelper;
pub(super) fn receive_and_get_newest_or_important_command(receiver : &Receiver<UiToHelper>) -> Result<NewestMostImportantCommand, RecvError> {
let first_message = receive_and_log_error(receiver)?;
Ok(get_newest_or_important_command(first_message, receiver.try_iter()))
}
pub(super) struct NewestMostImportantCommand(pub UiToHelper);
trait GetNewerOrMoreImportantCommand {
type Output;
fn get_newer_or_more_important_command(old: Self::Output, new: Self) -> Self::Output;
fn convert_first_command(self) -> Self::Output;
}
impl GetNewerOrMoreImportantCommand for UiToHelper {
type Output = NewestMostImportantCommand;
fn convert_first_command(self) -> Self::Output{
NewestMostImportantCommand(self)
}
fn get_newer_or_more_important_command(old: Self::Output, new: Self) -> Self::Output {
match old.0 {
UiToHelper::Shutdown => old,
UiToHelper::GeneratePassword(_) => NewestMostImportantCommand(new),
}
}
}
fn get_newest_or_important_command<I, It >(first_message: I, other_messages: It) -> I::Output
where I: GetNewerOrMoreImportantCommand,
It: Iterator<Item=I>
{
other_messages.fold(first_message.convert_first_command(), I::get_newer_or_more_important_command)
}
fn receive_and_log_error(receiver : &Receiver<UiToHelper>) -> Result<UiToHelper, RecvError> {
match receiver.recv() {
Ok(x) => Ok(x),
e => {
eprintln!("Connection to UI Thread closed unexpectedly.");
e
}
}
}
#[cfg(test)]
mod message_parsing_tests {
use super::*;
#[derive(PartialEq, Debug)]
enum TestPrioritizedEnum {
Lowest(usize),
Highest(usize),
Medium(usize)
}
impl TestPrioritizedEnum{
fn get_prio(&self) -> usize{
match self {
TestPrioritizedEnum::Lowest(_) => 0,
TestPrioritizedEnum::Highest(_) => 2,
TestPrioritizedEnum::Medium(_) => 1,
}
}
}
struct TestPrioritizedEnumPrioResult(TestPrioritizedEnum);
impl GetNewerOrMoreImportantCommand for TestPrioritizedEnum {
type Output = TestPrioritizedEnumPrioResult;
fn get_newer_or_more_important_command(old: Self::Output, new: Self) -> Self::Output {
if old.0.get_prio() > new.get_prio() { old } else { TestPrioritizedEnumPrioResult(new) }
}
fn convert_first_command(self) -> Self::Output {
TestPrioritizedEnumPrioResult(self)
}
}
#[test]
fn test_get_newest_or_important_command_test(){
let input1 = vec![TestPrioritizedEnum::Lowest(0), TestPrioritizedEnum::Lowest(1), TestPrioritizedEnum::Lowest(2)];
let expected1 = TestPrioritizedEnum::Lowest(2);
let input2 = vec![TestPrioritizedEnum::Medium(0), TestPrioritizedEnum::Lowest(1), TestPrioritizedEnum::Lowest(2)];
let expected2 = TestPrioritizedEnum::Medium(0);
let input3 = vec![TestPrioritizedEnum::Lowest(0), TestPrioritizedEnum::Medium(1), TestPrioritizedEnum::Lowest(2)];
let expected3 = TestPrioritizedEnum::Medium(1);
let input4 = vec![TestPrioritizedEnum::Medium(0), TestPrioritizedEnum::Lowest(1), TestPrioritizedEnum::Medium(2)];
let expected4 = TestPrioritizedEnum::Medium(2);
let input5 = vec![TestPrioritizedEnum::Lowest(0), TestPrioritizedEnum::Lowest(1), TestPrioritizedEnum::Highest(2), TestPrioritizedEnum::Medium(3)];
let expected5 = TestPrioritizedEnum::Highest(2);
let data = vec![(input1, expected1), (input2, expected2), (input3, expected3), (input4, expected4), (input5, expected5)];
for (input, expected) in data {
let mut it = input.into_iter();
let first = it.next().unwrap();
let result = get_newest_or_important_command(first,it);
assert_eq!(result.0, expected);
}
}
}
|