15317bbafSopenharmony_ci/* 25317bbafSopenharmony_ci * QR Code generator demo (Rust) 35317bbafSopenharmony_ci * 45317bbafSopenharmony_ci * Run this command-line program with no arguments. The program computes a bunch of demonstration 55317bbafSopenharmony_ci * QR Codes and prints them to the console. Also, the SVG code for one QR Code is printed as a sample. 65317bbafSopenharmony_ci * 75317bbafSopenharmony_ci * Copyright (c) Project Nayuki. (MIT License) 85317bbafSopenharmony_ci * https://www.nayuki.io/page/qr-code-generator-library 95317bbafSopenharmony_ci * 105317bbafSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy of 115317bbafSopenharmony_ci * this software and associated documentation files (the "Software"), to deal in 125317bbafSopenharmony_ci * the Software without restriction, including without limitation the rights to 135317bbafSopenharmony_ci * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 145317bbafSopenharmony_ci * the Software, and to permit persons to whom the Software is furnished to do so, 155317bbafSopenharmony_ci * subject to the following conditions: 165317bbafSopenharmony_ci * - The above copyright notice and this permission notice shall be included in 175317bbafSopenharmony_ci * all copies or substantial portions of the Software. 185317bbafSopenharmony_ci * - The Software is provided "as is", without warranty of any kind, express or 195317bbafSopenharmony_ci * implied, including but not limited to the warranties of merchantability, 205317bbafSopenharmony_ci * fitness for a particular purpose and noninfringement. In no event shall the 215317bbafSopenharmony_ci * authors or copyright holders be liable for any claim, damages or other 225317bbafSopenharmony_ci * liability, whether in an action of contract, tort or otherwise, arising from, 235317bbafSopenharmony_ci * out of or in connection with the Software or the use or other dealings in the 245317bbafSopenharmony_ci * Software. 255317bbafSopenharmony_ci */ 265317bbafSopenharmony_ci 275317bbafSopenharmony_ciextern crate qrcodegen; 285317bbafSopenharmony_ciuse qrcodegen::Mask; 295317bbafSopenharmony_ciuse qrcodegen::QrCode; 305317bbafSopenharmony_ciuse qrcodegen::QrCodeEcc; 315317bbafSopenharmony_ciuse qrcodegen::QrSegment; 325317bbafSopenharmony_ciuse qrcodegen::Version; 335317bbafSopenharmony_ci 345317bbafSopenharmony_ci 355317bbafSopenharmony_ci// The main application program. 365317bbafSopenharmony_cifn main() { 375317bbafSopenharmony_ci do_basic_demo(); 385317bbafSopenharmony_ci do_variety_demo(); 395317bbafSopenharmony_ci do_segment_demo(); 405317bbafSopenharmony_ci do_mask_demo(); 415317bbafSopenharmony_ci} 425317bbafSopenharmony_ci 435317bbafSopenharmony_ci 445317bbafSopenharmony_ci 455317bbafSopenharmony_ci/*---- Demo suite ----*/ 465317bbafSopenharmony_ci 475317bbafSopenharmony_ci// Creates a single QR Code, then prints it to the console. 485317bbafSopenharmony_cifn do_basic_demo() { 495317bbafSopenharmony_ci let text: &'static str = "Hello, world!"; // User-supplied Unicode text 505317bbafSopenharmony_ci let errcorlvl: QrCodeEcc = QrCodeEcc::Low; // Error correction level 515317bbafSopenharmony_ci 525317bbafSopenharmony_ci // Make and print the QR Code symbol 535317bbafSopenharmony_ci let qr: QrCode = QrCode::encode_text(text, errcorlvl).unwrap(); 545317bbafSopenharmony_ci print_qr(&qr); 555317bbafSopenharmony_ci println!("{}", to_svg_string(&qr, 4)); 565317bbafSopenharmony_ci} 575317bbafSopenharmony_ci 585317bbafSopenharmony_ci 595317bbafSopenharmony_ci// Creates a variety of QR Codes that exercise different features of the library, and prints each one to the console. 605317bbafSopenharmony_cifn do_variety_demo() { 615317bbafSopenharmony_ci // Numeric mode encoding (3.33 bits per digit) 625317bbafSopenharmony_ci let qr = QrCode::encode_text("314159265358979323846264338327950288419716939937510", QrCodeEcc::Medium).unwrap(); 635317bbafSopenharmony_ci print_qr(&qr); 645317bbafSopenharmony_ci 655317bbafSopenharmony_ci // Alphanumeric mode encoding (5.5 bits per character) 665317bbafSopenharmony_ci let qr = QrCode::encode_text("DOLLAR-AMOUNT:$39.87 PERCENTAGE:100.00% OPERATIONS:+-*/", QrCodeEcc::High).unwrap(); 675317bbafSopenharmony_ci print_qr(&qr); 685317bbafSopenharmony_ci 695317bbafSopenharmony_ci // Unicode text as UTF-8 705317bbafSopenharmony_ci let qr = QrCode::encode_text("こんにちwa、世界! αβγδ", QrCodeEcc::Quartile).unwrap(); 715317bbafSopenharmony_ci print_qr(&qr); 725317bbafSopenharmony_ci 735317bbafSopenharmony_ci // Moderately large QR Code using longer text (from Lewis Carroll's Alice in Wonderland) 745317bbafSopenharmony_ci let qr = QrCode::encode_text(concat!( 755317bbafSopenharmony_ci "Alice was beginning to get very tired of sitting by her sister on the bank, ", 765317bbafSopenharmony_ci "and of having nothing to do: once or twice she had peeped into the book her sister was reading, ", 775317bbafSopenharmony_ci "but it had no pictures or conversations in it, 'and what is the use of a book,' thought Alice ", 785317bbafSopenharmony_ci "'without pictures or conversations?' So she was considering in her own mind (as well as she could, ", 795317bbafSopenharmony_ci "for the hot day made her feel very sleepy and stupid), whether the pleasure of making a ", 805317bbafSopenharmony_ci "daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly ", 815317bbafSopenharmony_ci "a White Rabbit with pink eyes ran close by her."), QrCodeEcc::High).unwrap(); 825317bbafSopenharmony_ci print_qr(&qr); 835317bbafSopenharmony_ci} 845317bbafSopenharmony_ci 855317bbafSopenharmony_ci 865317bbafSopenharmony_ci// Creates QR Codes with manually specified segments for better compactness. 875317bbafSopenharmony_cifn do_segment_demo() { 885317bbafSopenharmony_ci // Illustration "silver" 895317bbafSopenharmony_ci let silver0 = "THE SQUARE ROOT OF 2 IS 1."; 905317bbafSopenharmony_ci let silver1 = "41421356237309504880168872420969807856967187537694807317667973799"; 915317bbafSopenharmony_ci let qr = QrCode::encode_text(&[silver0, silver1].concat(), QrCodeEcc::Low).unwrap(); 925317bbafSopenharmony_ci print_qr(&qr); 935317bbafSopenharmony_ci 945317bbafSopenharmony_ci let segs = vec![ 955317bbafSopenharmony_ci QrSegment::make_alphanumeric(silver0), 965317bbafSopenharmony_ci QrSegment::make_numeric(silver1), 975317bbafSopenharmony_ci ]; 985317bbafSopenharmony_ci let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap(); 995317bbafSopenharmony_ci print_qr(&qr); 1005317bbafSopenharmony_ci 1015317bbafSopenharmony_ci // Illustration "golden" 1025317bbafSopenharmony_ci let golden0 = "Golden ratio φ = 1."; 1035317bbafSopenharmony_ci let golden1 = "6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374"; 1045317bbafSopenharmony_ci let golden2 = "......"; 1055317bbafSopenharmony_ci let qr = QrCode::encode_text(&[golden0, golden1, golden2].concat(), QrCodeEcc::Low).unwrap(); 1065317bbafSopenharmony_ci print_qr(&qr); 1075317bbafSopenharmony_ci 1085317bbafSopenharmony_ci let segs = vec![ 1095317bbafSopenharmony_ci QrSegment::make_bytes(golden0.as_bytes()), 1105317bbafSopenharmony_ci QrSegment::make_numeric(golden1), 1115317bbafSopenharmony_ci QrSegment::make_alphanumeric(golden2), 1125317bbafSopenharmony_ci ]; 1135317bbafSopenharmony_ci let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap(); 1145317bbafSopenharmony_ci print_qr(&qr); 1155317bbafSopenharmony_ci 1165317bbafSopenharmony_ci // Illustration "Madoka": kanji, kana, Cyrillic, full-width Latin, Greek characters 1175317bbafSopenharmony_ci let madoka = "「魔法少女まどか☆マギカ」って、 ИАИ desu κα?"; 1185317bbafSopenharmony_ci let qr = QrCode::encode_text(madoka, QrCodeEcc::Low).unwrap(); 1195317bbafSopenharmony_ci print_qr(&qr); 1205317bbafSopenharmony_ci 1215317bbafSopenharmony_ci let kanjichars: Vec<u32> = vec![ // Kanji mode encoding (13 bits per character) 1225317bbafSopenharmony_ci 0x0035, 0x1002, 0x0FC0, 0x0AED, 0x0AD7, 1235317bbafSopenharmony_ci 0x015C, 0x0147, 0x0129, 0x0059, 0x01BD, 1245317bbafSopenharmony_ci 0x018D, 0x018A, 0x0036, 0x0141, 0x0144, 1255317bbafSopenharmony_ci 0x0001, 0x0000, 0x0249, 0x0240, 0x0249, 1265317bbafSopenharmony_ci 0x0000, 0x0104, 0x0105, 0x0113, 0x0115, 1275317bbafSopenharmony_ci 0x0000, 0x0208, 0x01FF, 0x0008, 1285317bbafSopenharmony_ci ]; 1295317bbafSopenharmony_ci let mut bb = qrcodegen::BitBuffer(Vec::new()); 1305317bbafSopenharmony_ci for &c in &kanjichars { 1315317bbafSopenharmony_ci bb.append_bits(c, 13); 1325317bbafSopenharmony_ci } 1335317bbafSopenharmony_ci let segs = vec![ 1345317bbafSopenharmony_ci QrSegment::new(qrcodegen::QrSegmentMode::Kanji, kanjichars.len(), bb.0), 1355317bbafSopenharmony_ci ]; 1365317bbafSopenharmony_ci let qr = QrCode::encode_segments(&segs, QrCodeEcc::Low).unwrap(); 1375317bbafSopenharmony_ci print_qr(&qr); 1385317bbafSopenharmony_ci} 1395317bbafSopenharmony_ci 1405317bbafSopenharmony_ci 1415317bbafSopenharmony_ci// Creates QR Codes with the same size and contents but different mask patterns. 1425317bbafSopenharmony_cifn do_mask_demo() { 1435317bbafSopenharmony_ci // Project Nayuki URL 1445317bbafSopenharmony_ci let segs = QrSegment::make_segments("https://www.nayuki.io/"); 1455317bbafSopenharmony_ci let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, Version::MIN, Version::MAX, None, true).unwrap(); // Automatic mask 1465317bbafSopenharmony_ci print_qr(&qr); 1475317bbafSopenharmony_ci let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::High, Version::MIN, Version::MAX, Some(Mask::new(3)), true).unwrap(); // Force mask 3 1485317bbafSopenharmony_ci print_qr(&qr); 1495317bbafSopenharmony_ci 1505317bbafSopenharmony_ci // Chinese text as UTF-8 1515317bbafSopenharmony_ci let segs = QrSegment::make_segments("維基百科(Wikipedia,聆聽i/ˌwɪkᵻˈpiːdi.ə/)是一個自由內容、公開編輯且多語言的網路百科全書協作計畫"); 1525317bbafSopenharmony_ci let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, Version::MIN, Version::MAX, Some(Mask::new(0)), true).unwrap(); // Force mask 0 1535317bbafSopenharmony_ci print_qr(&qr); 1545317bbafSopenharmony_ci let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, Version::MIN, Version::MAX, Some(Mask::new(1)), true).unwrap(); // Force mask 1 1555317bbafSopenharmony_ci print_qr(&qr); 1565317bbafSopenharmony_ci let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, Version::MIN, Version::MAX, Some(Mask::new(5)), true).unwrap(); // Force mask 5 1575317bbafSopenharmony_ci print_qr(&qr); 1585317bbafSopenharmony_ci let qr = QrCode::encode_segments_advanced(&segs, QrCodeEcc::Medium, Version::MIN, Version::MAX, Some(Mask::new(7)), true).unwrap(); // Force mask 7 1595317bbafSopenharmony_ci print_qr(&qr); 1605317bbafSopenharmony_ci} 1615317bbafSopenharmony_ci 1625317bbafSopenharmony_ci 1635317bbafSopenharmony_ci 1645317bbafSopenharmony_ci/*---- Utilities ----*/ 1655317bbafSopenharmony_ci 1665317bbafSopenharmony_ci// Returns a string of SVG code for an image depicting 1675317bbafSopenharmony_ci// the given QR Code, with the given number of border modules. 1685317bbafSopenharmony_ci// The string always uses Unix newlines (\n), regardless of the platform. 1695317bbafSopenharmony_cifn to_svg_string(qr: &QrCode, border: i32) -> String { 1705317bbafSopenharmony_ci assert!(border >= 0, "Border must be non-negative"); 1715317bbafSopenharmony_ci let mut result = String::new(); 1725317bbafSopenharmony_ci result += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"; 1735317bbafSopenharmony_ci result += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"; 1745317bbafSopenharmony_ci let dimension = qr.size().checked_add(border.checked_mul(2).unwrap()).unwrap(); 1755317bbafSopenharmony_ci result += &format!( 1765317bbafSopenharmony_ci "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 {0} {0}\" stroke=\"none\">\n", dimension); 1775317bbafSopenharmony_ci result += "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n"; 1785317bbafSopenharmony_ci result += "\t<path d=\""; 1795317bbafSopenharmony_ci for y in 0 .. qr.size() { 1805317bbafSopenharmony_ci for x in 0 .. qr.size() { 1815317bbafSopenharmony_ci if qr.get_module(x, y) { 1825317bbafSopenharmony_ci if x != 0 || y != 0 { 1835317bbafSopenharmony_ci result += " "; 1845317bbafSopenharmony_ci } 1855317bbafSopenharmony_ci result += &format!("M{},{}h1v1h-1z", x + border, y + border); 1865317bbafSopenharmony_ci } 1875317bbafSopenharmony_ci } 1885317bbafSopenharmony_ci } 1895317bbafSopenharmony_ci result += "\" fill=\"#000000\"/>\n"; 1905317bbafSopenharmony_ci result += "</svg>\n"; 1915317bbafSopenharmony_ci result 1925317bbafSopenharmony_ci} 1935317bbafSopenharmony_ci 1945317bbafSopenharmony_ci 1955317bbafSopenharmony_ci// Prints the given QrCode object to the console. 1965317bbafSopenharmony_cifn print_qr(qr: &QrCode) { 1975317bbafSopenharmony_ci let border: i32 = 4; 1985317bbafSopenharmony_ci for y in -border .. qr.size() + border { 1995317bbafSopenharmony_ci for x in -border .. qr.size() + border { 2005317bbafSopenharmony_ci let c: char = if qr.get_module(x, y) { '█' } else { ' ' }; 2015317bbafSopenharmony_ci print!("{0}{0}", c); 2025317bbafSopenharmony_ci } 2035317bbafSopenharmony_ci println!(); 2045317bbafSopenharmony_ci } 2055317bbafSopenharmony_ci println!(); 2065317bbafSopenharmony_ci} 207