Browse Source

项目结构整理

marion 5 years ago
parent
commit
c83920b3ea

+ 0 - 373
Cargo.lock

@@ -1,378 +1,5 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
-[[package]]
-name = "adler32"
-version = "1.0.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
-
-[[package]]
-name = "autocfg"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
-
-[[package]]
-name = "base64"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3"
-
-[[package]]
-name = "bitflags"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
-
-[[package]]
-name = "bytemuck"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
-
-[[package]]
-name = "byteorder"
-version = "1.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
-
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-
-[[package]]
-name = "checked_int_cast"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919"
-
-[[package]]
-name = "color_quant"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
-
-[[package]]
-name = "crc32fast"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "crossbeam-deque"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285"
-dependencies = [
- "crossbeam-epoch",
- "crossbeam-utils",
- "maybe-uninit",
-]
-
-[[package]]
-name = "crossbeam-epoch"
-version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
-dependencies = [
- "autocfg",
- "cfg-if",
- "crossbeam-utils",
- "lazy_static",
- "maybe-uninit",
- "memoffset",
- "scopeguard",
-]
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
-dependencies = [
- "autocfg",
- "cfg-if",
- "lazy_static",
-]
-
-[[package]]
-name = "deflate"
-version = "0.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "050ef6de42a33903b30a7497b76b40d3d58691d4d3eec355348c122444a388f0"
-dependencies = [
- "adler32",
- "byteorder",
-]
-
-[[package]]
-name = "either"
-version = "1.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
-
-[[package]]
-name = "gif"
-version = "0.10.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af"
-dependencies = [
- "color_quant",
- "lzw",
-]
-
 [[package]]
 name = "hello-rust"
 version = "0.1.0"
-dependencies = [
- "base64",
- "image",
- "qrcode",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1010591b26bbfe835e9faeabeb11866061cc7dcebffd56ad7d0942d0e61aefd8"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "image"
-version = "0.23.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "403f0c29211dc50a78eb53eeeae87945d44cb63071881834212f36677fccb2b4"
-dependencies = [
- "bytemuck",
- "byteorder",
- "gif",
- "jpeg-decoder",
- "num-iter",
- "num-rational",
- "num-traits",
- "png",
- "scoped_threadpool",
- "tiff",
-]
-
-[[package]]
-name = "inflate"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
-dependencies = [
- "adler32",
-]
-
-[[package]]
-name = "jpeg-decoder"
-version = "0.1.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0256f0aec7352539102a9efbcb75543227b7ab1117e0f95450023af730128451"
-dependencies = [
- "byteorder",
- "rayon",
-]
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-
-[[package]]
-name = "libc"
-version = "0.2.67"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
-
-[[package]]
-name = "lzw"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
-
-[[package]]
-name = "maybe-uninit"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
-
-[[package]]
-name = "memoffset"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
-dependencies = [
- "rustc_version",
-]
-
-[[package]]
-name = "miniz_oxide"
-version = "0.3.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa679ff6578b1cddee93d7e82e263b94a575e0bfced07284eb0c037c1d2416a5"
-dependencies = [
- "adler32",
-]
-
-[[package]]
-name = "num-integer"
-version = "0.1.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
-dependencies = [
- "autocfg",
- "num-traits",
-]
-
-[[package]]
-name = "num-iter"
-version = "0.1.40"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-rational"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da4dc79f9e6c81bef96148c8f6b8e72ad4541caa4a24373e900a36da07de03a3"
-dependencies = [
- "autocfg",
- "num-integer",
- "num-traits",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num_cpus"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
-dependencies = [
- "hermit-abi",
- "libc",
-]
-
-[[package]]
-name = "png"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46060468187c21c00ffa2a920690b29997d7fd543f5a4d400461e4a7d4fccde8"
-dependencies = [
- "bitflags",
- "crc32fast",
- "deflate",
- "inflate",
-]
-
-[[package]]
-name = "qrcode"
-version = "0.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16d2f1455f3630c6e5107b4f2b94e74d76dea80736de0981fd27644216cff57f"
-dependencies = [
- "checked_int_cast",
- "image",
-]
-
-[[package]]
-name = "rayon"
-version = "1.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098"
-dependencies = [
- "crossbeam-deque",
- "either",
- "rayon-core",
-]
-
-[[package]]
-name = "rayon-core"
-version = "1.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9"
-dependencies = [
- "crossbeam-deque",
- "crossbeam-queue",
- "crossbeam-utils",
- "lazy_static",
- "num_cpus",
-]
-
-[[package]]
-name = "rustc_version"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-dependencies = [
- "semver",
-]
-
-[[package]]
-name = "scoped_threadpool"
-version = "0.1.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-dependencies = [
- "semver-parser",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-
-[[package]]
-name = "tiff"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "002351e428db1eb1d8656d4ca61947c3519ac3191e1c804d4600cd32093b77ad"
-dependencies = [
- "byteorder",
- "lzw",
- "miniz_oxide",
-]

+ 1 - 8
Cargo.toml

@@ -6,11 +6,4 @@ edition = "2018"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
-[dependencies]
-#ferris-says = "0.1.1"
-#rand = "0.7.3"
-#chrono = "0.4.11"
-image = "0.23.1"
-qrcode = "0.12.0"
-#leptess = "0.8.1"
-base64 = "0.12.0"
+[dependencies]

+ 1 - 0
src/keygen/mod.rs → src/keygen_test/keygen/mod.rs

@@ -1,6 +1,7 @@
 mod snowflake_keygen;
 
 // 也可以 pub use XXX 直接导出更内层的对象或方法
+// self 是当前模块所在项目层级,supper 是上一级,包括单文件模块上一级即相同目录的mod.rs,crate 是引用的包,实际是从项目入口即src目录开始
 use self::snowflake_keygen::SnowflakeKeygen;
 
 pub fn next_id() -> u64 {

+ 1 - 1
src/keygen/snowflake_keygen.rs → src/keygen_test/keygen/snowflake_keygen.rs

@@ -1,7 +1,7 @@
 use std::{thread, time};
 use std::sync::RwLock;
 use chrono::prelude::*;
-use crate::keygen::IProgramKeygen;
+use super::IProgramKeygen;
 
 // 时间单位,一纳秒的多少倍,1e6 = 一毫秒,1e7 = 百分之一秒,1e8 = 十分之一秒
 const SNOWFLAKE_TIME_UNIT: i64 = (1e7 as i64);

+ 73 - 0
src/keygen_test/mod.rs

@@ -0,0 +1,73 @@
+// [dependencies]
+// chrono = "0.4.11"
+
+mod keygen;
+
+use std::thread;
+use std::sync::mpsc;
+use std::collections::HashMap;
+use chrono::prelude::*;
+
+pub fn test() {
+    let id = keygen::next_id();
+    println!("key from keygen:{}", id);
+    println!();
+    test_next_id();
+}
+
+fn test_next_id() {
+    let id_size = 100000;
+
+    let start_time = Utc::now().timestamp_nanos();
+    let (tx, rx) = mpsc::channel();
+
+
+    for _ in 0..id_size {
+        let tx = tx.clone();
+        thread::spawn(move || {
+            let id = keygen::next_id();
+            tx.send(id).unwrap()
+        });
+    };
+
+    let (tx2, rx2) = mpsc::channel();
+    let tx2 = tx2.clone();
+    let handle = thread::spawn(move || {
+        let mut m: HashMap<u64, i32> = HashMap::new();
+        let mut i = id_size;
+        loop {
+            let id = rx.recv().unwrap();
+            //let mut wrap = wrap.lock().unwrap();
+            if m.contains_key(&id) {
+                let v = *(m.get_mut(&id).unwrap());
+                m.insert(id, v + 1);
+            } else {
+                m.insert(id, 1);
+            }
+            i -= 1;
+            if i == 0 {
+                break;
+            }
+        }
+        tx2.send(m).unwrap();
+    });
+
+    handle.join().expect("The thread being joined has panicked");
+
+    let m = rx2.recv().unwrap();
+
+    let end_time = Utc::now().timestamp_nanos();
+    let used_time = end_time - start_time;
+    println!("Id size: {}\nTotal seconds:{}\nAvg nanos per id:{}", m.len(), used_time / 1000000000, (used_time as i64) / (id_size as i64));
+
+    let mut bad_size = 0;
+    for (_, v) in m.iter() {
+        if *v > 1 {
+            bad_size += 1;
+        }
+    }
+
+    if bad_size > 0 {
+        println!("Not good")
+    }
+}

+ 7 - 142
src/main.rs

@@ -2,151 +2,16 @@
 // 库的入口文件统一命名为lib.rs
 
 // 引用模块
-// mod test;
-// mod keygen;
+// mod random_test;
+// mod keygen_test;
+// mod qr_code_test;
 
 // 将其他模块的成员声明为当前模块直接可用的,等同于java的静态引用
 // 若省略这句,下面不可以直接使用Random结构体,而需要加上模块名,即test::Random
-// use self::test::Random;
-//
-// use std::thread;
-// use std::sync::mpsc;
-// use std::collections::HashMap;
-// use chrono::prelude::*;
-//
-// use std::io::{stdout, BufWriter};
-// use ferris_says::say;
+// use self::random_test::{test, Random};
 
 fn main() {
-    // let stdout = stdout();
-    // let out = b"Hello fellow Rustaceans!";
-    // let width = 24;
-    //
-    // let mut writer = BufWriter::new(stdout.lock());
-    // say(out, width, &mut writer).unwrap(); // unwrap为rust预定义错误处理模式,正常时返回OK值,错误时panic!
-    //
-    // let rd = Random { seed: 100 };
-    // println!("a random number:{}", rd.next());
-    // let id = keygen::next_id();
-    // println!("key from keygen:{}", id);
-    // println!();
-    // test_next_id();
-
-    // QRCode
-    let arr_first = [
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
-    ];
-    let arr_domain = [
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-',
-        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
-        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
-    ];
-    for size in 2..47 { // 英文域名长度2到46个字符
-        for c in arr_first.iter() {
-            walk(format!("{}", c).as_str(), size - 1, &arr_domain)
-        }
-    }
-
-    // OCR
-    // let mut lt = leptess::LepTess::new(None, "chi_sim").unwrap();
-    // lt.set_image("./tmp/qrcode.png");
-    // println!("OCR result:{}", lt.get_utf8_text().unwrap());
-}
-
-fn walk(s: &str, level: i32, arr: &[char]) {
-    for c in arr.iter() {
-        let new_s = format!("{}{}", s, c);
-        if level == 0 {
-            let data_http = format!("http://{}.com", new_s);
-            qr_code_gen(data_http.as_str());
-
-            let data_https = format!("https://{}.com", new_s);
-            qr_code_gen(data_https.as_str());
-        } else {
-            walk(new_s.as_str(), level - 1, arr)
-        }
-    }
-}
-
-fn qr_code_gen(data: &str) {
-    //println!("QR code for {}", data);
-
-    let out_path = "./tmp";
-    let name = base64::encode(data);
-
-    let code_m = qrcode::QrCode::new(data).unwrap();
-    let image_m = code_m.render::<image::Luma<u8>>().build();
-    image_m.save(format!("{}/{}_M.png", out_path, name)).unwrap();
-
-    let code_l = qrcode::QrCode::with_error_correction_level(data, qrcode::EcLevel::L).unwrap();
-    let image_l = code_l.render::<image::Luma<u8>>().build();
-    image_l.save(format!("{}/{}_L.png", out_path, name)).unwrap();
-
-    let code_q = qrcode::QrCode::with_error_correction_level(data, qrcode::EcLevel::Q).unwrap();
-    let image_q = code_q.render::<image::Luma<u8>>().build();
-    image_q.save(format!("{}/{}_Q.png", out_path, name)).unwrap();
-
-    let code_h = qrcode::QrCode::with_error_correction_level(data, qrcode::EcLevel::H).unwrap();
-    let image_h = code_h.render::<image::Luma<u8>>().build();
-    image_h.save(format!("{}/{}_H.png", out_path, name)).unwrap();
+    // random_test::test();
+    // keygen_test::test();
+    // qr_code_test::test(2, 3);
 }
-
-// fn test_next_id() {
-//     let id_size = 100000;
-//
-//     let start_time = Utc::now().timestamp_nanos();
-//     let (tx, rx) = mpsc::channel();
-//
-//
-//     for _ in 0..id_size {
-//         let tx = tx.clone();
-//         thread::spawn(move || {
-//             let id = keygen::next_id();
-//             tx.send(id).unwrap()
-//         });
-//     };
-//
-//     let (tx2, rx2) = mpsc::channel();
-//     let tx2 = tx2.clone();
-//     let handle = thread::spawn(move || {
-//         let mut m: HashMap<u64, i32> = HashMap::new();
-//         let mut i = id_size;
-//         loop {
-//             let id = rx.recv().unwrap();
-//             //let mut wrap = wrap.lock().unwrap();
-//             if m.contains_key(&id) {
-//                 let v = *(m.get_mut(&id).unwrap());
-//                 m.insert(id, v + 1);
-//             } else {
-//                 m.insert(id, 1);
-//             }
-//             i -= 1;
-//             if i == 0 {
-//                 break;
-//             }
-//         }
-//         tx2.send(m).unwrap();
-//     });
-//
-//     handle.join().expect("The thread being joined has panicked");
-//
-//     let m = rx2.recv().unwrap();
-//
-//     let end_time = Utc::now().timestamp_nanos();
-//     let used_time = end_time - start_time;
-//     println!("Id size: {}\nTotal seconds:{}\nAvg nanos per id:{}", m.len(), used_time / 1000000000, (used_time as i64) / (id_size as i64));
-//
-//     let mut bad_size = 0;
-//     for (_, v) in m.iter() {
-//         if *v > 1 {
-//             bad_size += 1;
-//         }
-//     }
-//
-//     if bad_size > 0 {
-//         println!("Not good")
-//     }
-// }
-

+ 69 - 0
src/qr_code_test/mod.rs

@@ -0,0 +1,69 @@
+// [dependencies]
+// image = "0.23.1"
+// qrcode = "0.12.0"
+// base64 = "0.12.0"
+// leptess = "0.8.1" # for OCR
+
+use qrcode::{QrCode, EcLevel};
+
+pub fn test(min: i32, max: i32) {
+    // QRCode
+    let arr_first = [
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
+    ];
+    let arr_domain = [
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-',
+        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
+    ];
+    for size in min..max { // 如英文域名长度2到46个字符,则min=2,max=47
+        for c in arr_first.iter() {
+            walk(format!("{}", c).as_str(), size - 1, &arr_domain)
+        }
+    }
+
+    // OCR
+    // let mut lt = leptess::LepTess::new(None, "chi_sim").unwrap();
+    // lt.set_image("./tmp/qrcode.png");
+    // println!("OCR result:{}", lt.get_utf8_text().unwrap());
+}
+
+fn walk(s: &str, level: i32, arr: &[char]) {
+    for c in arr.iter() {
+        let new_s = format!("{}{}", s, c);
+        if level == 0 {
+            let data_http = format!("http://{}.com", new_s);
+            qr_code_gen(data_http.as_str());
+
+            let data_https = format!("https://{}.com", new_s);
+            qr_code_gen(data_https.as_str());
+        } else {
+            walk(new_s.as_str(), level - 1, arr)
+        }
+    }
+}
+
+pub fn qr_code_gen(data: &str) {
+    println!("QR code for {}", data);
+
+    let out_path = "./tmp";
+    let name = base64::encode(data);
+
+    let code_m = QrCode::new(data).unwrap();
+    let image_m = code_m.render::<image::Luma<u8>>().build();
+    image_m.save(format!("{}/{}_M.png", out_path, name)).unwrap();
+
+    let code_l = QrCode::with_error_correction_level(data, EcLevel::L).unwrap();
+    let image_l = code_l.render::<image::Luma<u8>>().build();
+    image_l.save(format!("{}/{}_L.png", out_path, name)).unwrap();
+
+    let code_q = QrCode::with_error_correction_level(data, EcLevel::Q).unwrap();
+    let image_q = code_q.render::<image::Luma<u8>>().build();
+    image_q.save(format!("{}/{}_Q.png", out_path, name)).unwrap();
+
+    let code_h = QrCode::with_error_correction_level(data, EcLevel::H).unwrap();
+    let image_h = code_h.render::<image::Luma<u8>>().build();
+    image_h.save(format!("{}/{}_H.png", out_path, name)).unwrap();
+}

+ 9 - 0
src/test/mod.rs → src/random_test/mod.rs

@@ -1,7 +1,16 @@
 // 一个模块(子目录)下的入口文件,统一命名为mod.rs,模块下的其他文件需要公开的,在mod.rs中统一导出
+// 或者模块仅有单文件,则可以不用子目录而直接用单个文件作为一个模块,如random_test.rs
+
+// [dependencies]
+// rand = "0.7.3"
 
 use rand::prelude::*;
 
+pub fn test() {
+    let rd = Random { seed: 100 };
+    println!("a random number:{}", rd.next());
+}
+
 // 声明一个结构体
 pub struct Random {
     pub seed: i32 // 成员变量

+ 0 - 0
src/spider_test/mod.rs