1#![allow(unused_must_use)]
2
3use regex::Regex;
4use std::error::Error;
5use std::io::prelude::*;
6use std::path::Path;
7use std::borrow::Cow;
8use std::fs::File;
9use std::fs;
10
11pub mod features;
12
13const SPLIT_STR: &str = r#"//======="#;
14const FEATURE_STR: &str = r#"#[cfg(feature = "#;
15
16const END: &str = "\"#;";
17const FN_MAIN: &str = "adjoin";
18
19
20pub fn convert_all_rss() {
21 let path_str :&str = &format!("./examples");
22 let paths = fs::read_dir(path_str).unwrap();
23 for path in paths {
24 let p_name = path.unwrap().path();
25 match p_name.to_str() {
27 Some(folder_name) => {
28 if !folder_name.contains(".rs") {
29 let names: Vec<&str> = folder_name.split("/").collect();
31 println!("folder_name = {:?}", names[2]);
32 convert_rss(names[2]);
33 }
34 },
35 None => {}
36 }
37 }
38}
39
40
41pub fn convert_rss(folder_name: &str) {
42 let path_str :&str = &format!("./examples/{}", folder_name);
43 let paths = fs::read_dir(path_str).unwrap();
44
45 for path in paths {
46 let p = path.unwrap().path();
49 let f_name = p.file_name();
50 match f_name {
51 Some(file_name) => {
52 if file_name != "main.rs" {
53 let str = file_name.to_string_lossy();
54 let str :&str = &format!("{}", str);
55 let names: Vec<&str> = str.split(".").collect();
56 println!("file_name = {:?}", names[0]);
57 convert_rs(folder_name, names[0]);
58 }
59 },
60 None => {}
61 }
62 }
63}
64
65
66
67pub fn convert_rs(folder_name: &str, file_name: &str) {
68 let path_file :&str = &format!("./examples/{}/{}.rs", folder_name, file_name);
69 let source = read_rs(path_file, false);
70
71 let mut split: Vec<&str> = source.split(SPLIT_STR).collect();
73
74 let mut codes_str = String::new();
75 let split_len = split.len() - 1;
76 if split_len < 4 {
77 return;
78 }
79 let split1 = split[1];
80 for (index, item) in split.iter_mut().enumerate() {
81 if index > 1 && index < split_len {
82 let mut f = String::new();
83 let feature_name = &mut f;
84 let destination = format!("{}\n{}", split1, item);
85 let mut tmp = create_rs(destination, feature_name);
86
87 let begin_str = get_begin(file_name, feature_name);
89 tmp = format!("{}{}{}", begin_str, tmp, END);
90 codes_str = format!("{}\n\n{}", codes_str, tmp);
91
92 let path_file :&str = &format!("./src/features/rs_files.rs");
93 insert_mod_name(path_file, folder_name, file_name);
94 insert_code_name(path_file, folder_name, file_name, feature_name);
95 }
96 }
97
98 let path_file :&str = &format!("./src/features/rs_files/{}_{}.rs", folder_name, file_name);
99 write_rs(path_file, codes_str);
100 let path_file :&str = &format!("./src/bin/borrow.yml");
103 insert_example_name(path_file, folder_name, file_name);
104}
105
106
107
108fn get_begin<'de>(file_name: &'de str, feature_name: &'de str) -> Cow<'de, str>{
109 const BEGIN: &str = r#"pub const ------- :&str = r#""#;
110 let re_feature = Regex::new(r"-------").unwrap();
111 let replace_str = format!(
112 "{}_{}",
113 file_name.to_uppercase(),
114 feature_name.to_uppercase()
115 );
116 let begin_str = re_feature.replace(
117 BEGIN, replace_str.as_str()
118 );
119 begin_str
120}
121
122
123fn create_rs(destination :String, feature_name :&mut String) -> String {
124 let re_main = Regex::new(r"adjoin").unwrap();
125 let re_comment = Regex::new(r"^\s*//").unwrap();
126
127 let lines = destination.lines();
128 let mut codes_str = String::new();
129 let mut result;
130 for line in lines {
131 if line.contains(FN_MAIN) {
132 result = re_main.replace(line, "main");
133 codes_str = format!("{}{}\n", codes_str, result.as_ref());
134 } else if line.contains(FEATURE_STR) {
135 if line[0..10] == FEATURE_STR[0..10] {
136 let tmp: Vec<&str> = line.split("\"").collect();
137 feature_name.push_str(tmp[1]);
139 }
140 } else {
141 if !line.is_empty() {
142 result = re_comment.replace(line, "");
143 if line == result {
144 codes_str = format!("{}{}\n", codes_str, result.as_ref());
145 }
146 }
147 }
148 }
150
151 codes_str
152}
153
154fn insert_example_name(path_file :&str, folder_name :&str, file_name :&str) {
155 let mut source = read_rs(path_file, false);
156 let code_name = format!( "- {}_{}", folder_name, file_name );
157
158 if !source.contains(&code_name) {
159 const RE_STR: &str = r#"\#\#example_name"#;
161 const MUSTER_STR: &str = r#"##example_name"#;
162 let path_code_name :&str = &format!(
164 r#"{}
165 {}"#,
166 MUSTER_STR,
167 code_name
168 );
169 println!("path_code_name = {}", path_code_name);
170 let re_code = Regex::new(RE_STR).unwrap();
171 let result = re_code.replace_all(&source, path_code_name);
172 source = format!("{}", result);
173
174 write_rs(path_file, source);
175 } else {
176 println!("NOTHING insert_example_name !!!");
177 }
178}
179
180fn insert_code_name(path_file :&str, folder_name :&str, file_name :&str, feature_name :&str) {
181 let mut source = read_rs(path_file, false);
182 let code_name = format!(
183 "{}_{}_{}",
184 folder_name,
185 file_name,
186 feature_name
187 );
188
189 if !source.contains(&code_name) {
190 let comment_str: &str = &format!(r#"//{}"#, feature_name);
192 let re_str: &str = &format!("//{}\n", feature_name);
193 let path_code_name :&str = &format!(
194 r#""{}" => {}_{}::{}_{},
195 {}
196 "#,
197 code_name,
198 folder_name,
199 file_name,
200 file_name.to_uppercase(),
201 feature_name.to_uppercase(),
202 comment_str,
203 );
204 println!("path_code_name = {}", path_code_name);
205 let re_code = Regex::new(re_str).unwrap();
206 let result = re_code.replace_all(&source, path_code_name);
207 source = format!("{}", result);
208
209 write_rs(path_file, source);
210 } else {
211 }
213}
214
215
216
217fn insert_mod_name(path_file :&str, folder_name :&str, file_name :&str) {
218 let mut source = read_rs(path_file, false);
219 let code_name = format!(
220 "mod {}_{};",
221 folder_name,
222 file_name
223 );
224
225 if !source.contains(&code_name) {
226 let comment_str: &str = &format!(r#"//mod"#);
228 let re_str: &str = &format!("//mod\n");
229 let path_code_name :&str = &format!(
230 r#"{}
231{}
232 "#,
233 code_name,
234 comment_str,
235 );
236 println!("path_code_name = {}", path_code_name);
237 let re_code = Regex::new(re_str).unwrap();
238 let result = re_code.replace_all(&source, path_code_name);
239 source = format!("{}", result);
240
241 write_rs(path_file, source);
242 } else {
243 }
245}
246
247
248
249fn read_rs(file: &str, visible: bool) -> String {
252 let path = Path::new(file);
253 let display = path.display();
254
255 let mut file = match File::open(&path) {
257 Err(why) => panic!("couldn't open {}: {}", display, why.description()),
260 Ok(file) => file,
261 };
262
263 let mut s = String::new();
265 match file.read_to_string(&mut s) {
266 Err(why) => panic!("couldn't read {}: {}", display, why.description()),
267 Ok(_) => {
268 if visible {
269 print!("\n\n\n{} contains:\n{}\n\n\n", display, s);
270 } else {
271 print!("successfully read to\n{}\n\n", display);
272 }
273 }
274 }
275 s
276}
277
278fn write_rs(file: &str, stream: String) {
279 let new_path = Path::new(file);
281 let new_display = new_path.display();
282
283 let mut new_file = match File::create(&new_path) {
285 Err(why) => panic!("couldn't create {}: {}", new_display, why.description()),
286 Ok(new_file) => new_file,
287 };
288
289 match new_file.write_all(stream.as_bytes()) {
291 Err(why) => panic!("couldn't write to {}: {}", new_display, why.description()),
292 Ok(_) => println!("successfully wrote to\n{}\n\n", new_display),
293 }
294}
295
296pub fn allx_cmds(file_name: &str) {
321 let ret = format!(
322 r#"
323# Show this command
324cargo run --bin bw -- --code {0} | bat -l cmd
325cargo install borrowing_exerci
326bw --code {0}
327bw --code {0} | bat -l cmd
328
329# Show the Help for Rust File
330cargo run --bin bw -- --code <CODE>
331cargo install borrowing_exerci
332bw --code <CODE> | bat -l cmd
333
334# Run OK:
335cargo run --bin bw -- --code <CODE> --feature ok
336cargo run --example <CODE> --features ok
337cargo install borrowing_exerci
338bw --code <CODE> --feature ok
339
340# Compile-Time Error:
341cargo run --bin bw -- -c <CODE> -f err | bat -l rs
342cargo run --example <CODE> --features err
343cargo install borrowing_exerci
344bw --code <CODE> -f err | bat -l rs
345"#,
346 file_name
347 );
348 println!("{}", ret);
349}
350
351pub fn devx_cmds(file_name: &str) {
352 let ret = format!(
353 r#"
354# Show this Help for Developer
355cargo run --bin bw -- --file {0} | bat -l cmd
356../target/debug/bw --file {0} | bat -l cmd
357cargo install borrowing_exerci
358bw --file {0}
359bw --file {0} | bat -l cmd
360
361# Use the tool cargo-expand
362cargo expand --example {0} --features ok | bat -l cmd
363cargo expand --example {0} --features err | bat -l cmd
364RUSTFLAGS="--emit mir" cargo build --release --example {0} --features ok
365RUSTFLAGS="--emit mir" cargo build --release --example {0} --features err
366ls -al ../target/release/examples/{0}-*.mir
367open -t ../target/release/examples/{0}-*.mir
368
369# Show the Help for User
370cargo run --bin bw -- --file {0}
371../target/debug/bw --file {0}
372cargo install borrowing_exerci
373bw --file {0} | bat -l cmd
374
375# Run OK:
376cargo run --example {0} --features ok | bat -l cmd
377cargo run --bin bw -- --file {0} --mode ok | bat -l cmd
378../target/debug/bw --file {0} --mode ok | bat -l cmd
379cargo install borrowing_exerci
380bw --file {0} --mode ok
381
382# Compile-Time Error:
383cargo run --example {0} --features err | bat -l cmd
384cargo run --bin bw -- -f {0} -m err | bat -l rs
385../target/debug/bw --file {0} --mode err | bat -l cmd
386cargo install borrowing_exerci
387bw --file {0} -m err | bat -l rs
388"#,
389 file_name
390 );
391 println!("{}", ret);
392}
393
394pub fn user_cmds(file_name: &str) {
395 let ret = format!(
396 r#"
397// Show this command
398cargo install borrowing_exerci
399bw --code {0} | bat -l cmd
400
401// Run OK:
402cargo install borrowing_exerci
403bw --code <CODE> --feature ok | bat -l rs
404
405// Compile-Time Error:
406cargo install borrowing_exerci
407bw --code <CODE> -f err | bat -l rs
408"#,
409 file_name
410 );
411 println!("{}", ret);
412}
413
414pub fn hello() {
415 println!("{}", "Start... Hello Borrowing!");
416 println!("\n{}", "use this help for crate `borrowing_exerci`:");
417 println!("\t{}", "bw -h");
418 println!("\t{}", "bw --help");
419 println!("\n\n{}", "list all faetures for a code:");
420 println!("\t{}", "bw -- -c <code>");
421 println!("example:");
422 println!("\t{}", "bw --code closure_move_vec");
423 println!("\n\n{}", "run code for the `code` and the `feature`:");
424 println!("\t{}", "bw --code <code> --feature <feature>");
425 println!("example:");
426 println!("\t{}", "bw --code closure_move_vec --feature ok | bat -l rs ");
427 println!("\t{}", "tip: f");
428 println!("\t{}", "tip: q");
429}
430
431
432