context_walkthrough/
context_walkthrough.rs1use edit_session::{EditSession, FinishError};
4
5#[derive(Clone, Copy, PartialEq, Eq)]
6struct Context {
7 document: u64,
8 target: u64,
9 revision: u64,
10}
11
12struct Row {
13 action: &'static str,
14 live: u8,
15 revision: u64,
16 preview: u8,
17 value_matches_original: bool,
18 check: &'static str,
19}
20
21fn observe(
22 action: &'static str,
23 live: u8,
24 context: Context,
25 draft: &EditSession<u8, Context>,
26) -> Row {
27 let check = match draft.check(&live, &context) {
28 Ok(()) => "Ready",
29 Err(FinishError::ContextChanged) => "ContextChanged",
30 Err(FinishError::ValueChanged) => "ValueChanged",
31 Err(FinishError::InvalidProposal) => "InvalidProposal",
32 };
33 Row {
34 action,
35 live,
36 revision: context.revision,
37 preview: *draft.preview(),
38 value_matches_original: live == *draft.original(),
39 check,
40 }
41}
42
43fn main() {
44 let args: Vec<_> = std::env::args().skip(1).collect();
45 let json = match args.as_slice() {
46 [] => false,
47 [flag] if flag == "--json" => true,
48 _ => {
49 eprintln!("Usage: context_walkthrough [--json]");
50 std::process::exit(2);
51 }
52 };
53 let mut live = 100_u8;
54 let mut context = Context {
55 document: 7,
56 target: 2,
57 revision: 42,
58 };
59 let mut draft = EditSession::new(live, context);
60 assert_eq!(draft.propose::<&str>(Ok(75)), Ok(()));
61 let mut rows = vec![observe("Open draft", live, context, &draft)];
62 assert_eq!(draft.check(&live, &context), Ok(()));
63
64 live = 120;
66 context.revision += 1;
67 rows.push(observe("Host edits", live, context, &draft));
68 assert_eq!(
69 draft.check(&live, &context),
70 Err(FinishError::ContextChanged)
71 );
72
73 live = 100;
75 context.revision += 1;
76 rows.push(observe("Host undoes", live, context, &draft));
77 assert_eq!(live, *draft.original());
78 assert_eq!(
79 draft.check(&live, &context),
80 Err(FinishError::ContextChanged)
81 );
82
83 draft.reset();
85 rows.push(observe("Reset draft", live, context, &draft));
86 assert_eq!(*draft.preview(), live);
87 assert_eq!(draft.context().revision, 42);
88 assert_eq!(
89 draft.finish(&live, &context),
90 Err(FinishError::ContextChanged)
91 );
92
93 if json {
94 println!("{{\"rows\":[");
95 for (i, row) in rows.iter().enumerate() {
96 println!(
97 "{{\"action\":\"{}\",\"live\":{},\"revision\":{},\"preview\":{},\"value_matches_original\":{},\"check\":\"{}\"}}{}",
98 row.action,
99 row.live,
100 row.revision,
101 row.preview,
102 row.value_matches_original,
103 row.check,
104 if i + 1 == rows.len() { "" } else { "," }
105 );
106 }
107 println!("],\"finish\":\"ContextChanged\"}}");
108 } else {
109 println!("Action | Live | Revision | Preview | Value equals original | check()");
110 for row in &rows {
111 println!(
112 "{:<13} | {:>4} | {:>8} | {:>7} | {:<21} | {}",
113 row.action,
114 row.live,
115 row.revision,
116 row.preview,
117 row.value_matches_original,
118 row.check
119 );
120 }
121 println!("finish(): ContextChanged. The host must not apply the old draft.");
122 }
123}