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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use std::io;
pub fn stdin_read_line(input: &mut String) -> bool {
match io::stdin().read_line(input) {
Ok(_) => {},
Err(err) => {
println!("Error when read line from stdin: {}", err);
return false
},
}
true
}
pub fn stdin_readlines(input: &mut String) -> bool {
let eof = String::from("EOF");
stdin_readlines_end_with(input, &eof)
}
pub fn stdin_readlines_end_with(input: &mut String, eof: &String) -> bool {
let mut lines: Vec<String> = Vec::new();
let mut index = 0;
let mut failed_times = 0;
println!("> `{}` to stop reading from stdin, and `C_H` show help", eof.trim_end());
loop {
let mut line = String::new();
match io::stdin().read_line(&mut line) {
Ok(_) => {
if line.trim_end().eq(eof) {
break
}
if line.eq("C_H\n") {
show_help();
} else if line.eq("C_C\n") {
lines = Vec::new();
} else if line.eq("C_P\n") {
printlines(&lines);
} else if line.starts_with("C_D") {
let args: Vec<_> = line.split(" ").collect();
if args.len() == 1 {
if lines.len() > 1 {
lines.pop().unwrap();
index -= 1;
} else {
println!("No line to drop!");
}
} else if args.len() == 2 {
let max = lines.len();
if let Ok(num) = args[1].trim_end().parse::<usize>() {
if num < 1 {
println!("Delete line must in 1 to {}", max);
continue;
} else if num > max {
println!("Delete line must in 1 to {}", max);
continue;
}
lines.remove(index - 1);
index -= 1;
} else {
println!("Delete line must in 1 to {}", max);
show_help();
}
} else {
show_help();
}
} else if line.starts_with("C_I") {
let max = lines.len() + 1;
let args: Vec<_> = line.split(" ").collect();
if args.len() == 2 {
if let Ok(num) = args[1].trim_end().parse::<usize>() {
if num < 1 {
println!("Insert line must in 1 to {}", max);
continue;
} else if num > max {
println!("Insert line must in 1 to {}", max);
continue;
}
index = num - 1;
} else {}
} else {
show_help();
}
} else {
lines.insert(index, line);
index += 1;
}
},
Err(err) => {
println!("Error when read line from stdin: {}", err);
failed_times += 1;
if failed_times > 3 {
println!("Failed more than 3 times, stop and exit.");
return false
}
},
}
}
for line in &lines {
input.push_str(line);
}
true
}
fn show_help() {
let help_info = "
Usage:
C_H Show this help
C_C Clear all the inputed data
C_D [N] Delete the line N, or delete the last line
C_I [N] Move the insert index to line N
C_P print the current inputed lines, if more the than 10 lines,
every time print 10 lines, then you can input `n` to print
the next, use `q` to quit print mode
EOF Stop readlines
";
println!("{}", help_info);
}
fn printlines(lines: &Vec<String>) {
let mut num = 0;
let mut lnum = 1;
let mut input = String::new();
for line in lines {
print!("{:2} {}", lnum, line);
num += 1;
lnum += 1;
if num == 10 {
io::stdin().read_line(&mut input).unwrap();
if input.eq("n\n") {
num = 0;
} else if input.eq("q\n") {
break;
}
}
}
}