1use std::io;
2
3pub fn stdin_read_line(input: &mut String) -> bool {
5 match io::stdin().read_line(input) {
6 Ok(_) => {},
7 Err(err) => {
8 println!("Error when read line from stdin: {}", err);
9 return false
10 },
11 }
12
13 true
14}
15
16pub fn stdin_readlines(input: &mut String) -> bool {
18 let eof = String::from("EOF");
19 stdin_readlines_end_with(input, &eof)
20}
21
22pub fn stdin_readlines_end_with(input: &mut String, eof: &String) -> bool {
31 let mut lines: Vec<String> = Vec::new();
32 let mut index = 0;
33 let mut failed_times = 0;
34
35 println!("> `{}` to stop reading from stdin, and `C_H` show help", eof.trim_end());
36 loop {
38 let mut line = String::new();
39
40 match io::stdin().read_line(&mut line) {
41 Ok(_) => {
42 if line.trim_end().eq(eof) {
43 break
44 }
45 if line.eq("C_H\n") {
46 show_help();
47 } else if line.eq("C_C\n") {
48 lines = Vec::new();
49 } else if line.eq("C_P\n") {
50 printlines(&lines);
51 } else if line.starts_with("C_D") {
53 let args: Vec<_> = line.split(" ").collect();
54 if args.len() == 1 {
55 if lines.len() > 1 {
56 lines.pop().unwrap();
57 index -= 1;
59 } else {
60 println!("No line to drop!");
61 }
62 } else if args.len() == 2 {
63 let max = lines.len();
64 if let Ok(num) = args[1].trim_end().parse::<usize>() {
65 if num < 1 {
66 println!("Delete line must in 1 to {}", max);
67 continue;
68 } else if num > max {
69 println!("Delete line must in 1 to {}", max);
70 continue;
71 }
72 lines.remove(index - 1);
73 index -= 1;
75 } else {
76 println!("Delete line must in 1 to {}", max);
77 show_help();
78 }
79 } else {
80 show_help();
81 }
82 } else if line.starts_with("C_I") {
84 let max = lines.len() + 1;
85 let args: Vec<_> = line.split(" ").collect();
86 if args.len() == 2 {
87 if let Ok(num) = args[1].trim_end().parse::<usize>() {
88 if num < 1 {
89 println!("Insert line must in 1 to {}", max);
90 continue;
91 } else if num > max {
92 println!("Insert line must in 1 to {}", max);
93 continue;
94 }
95 index = num - 1;
96 } else {}
97 } else {
98 show_help();
99 }
100 } else {
101 lines.insert(index, line);
102 index += 1;
103 }
104 },
105 Err(err) => {
106 println!("Error when read line from stdin: {}", err);
107 failed_times += 1;
108 if failed_times > 3 {
109 println!("Failed more than 3 times, stop and exit.");
110 return false
111 }
112 },
113 }
114 }
115 for line in &lines {
116 input.push_str(line);
117 }
118
119 true
120}
121
122fn show_help() {
123 let help_info = "
124Usage:
125 C_H Show this help
126 C_C Clear all the inputed data
127 C_D [N] Delete the line N, or delete the last line
128 C_I [N] Move the insert index to line N
129 C_P print the current inputed lines, if more the than 10 lines,
130 every time print 10 lines, then you can input `n` to print
131 the next, use `q` to quit print mode
132 EOF Stop readlines
133";
134
135 println!("{}", help_info);
136}
137
138fn printlines(lines: &Vec<String>) {
139 let mut num = 0;
140 let mut lnum = 1;
141 let mut input = String::new();
142 for line in lines {
143 print!("{:2} {}", lnum, line);
144 num += 1;
145 lnum += 1;
146 if num == 10 {
147 io::stdin().read_line(&mut input).unwrap();
148 if input.eq("n\n") {
149 num = 0;
150 } else if input.eq("q\n") {
151 break;
152 }
153 }
154 }
155}