├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE ├── README.md ├── appveyor.yml ├── gh_rsa.enc ├── rustfmt.toml ├── src ├── lib.rs └── main.rs └── wustc.sublime-project /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: nabijaczleweli 2 | custom: https://www.paypal.me/nabijaczleweli 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.git* 3 | !.git*/** 4 | !.travis.yml 5 | !gh_rsa.enc 6 | !appveyor.yml 7 | !LICENSE 8 | !build.rs 9 | !Cargo.toml 10 | !rustfmt.toml 11 | !*.sublime-project 12 | !*.md 13 | !*.rc 14 | !src 15 | !src/** 16 | !tests 17 | !tests/** 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: generic 3 | cache: cargo 4 | 5 | matrix: 6 | include: 7 | - env: LANGUAGE=Rust DEPLOY=true DEPLOY_FILE="$TRAVIS_BUILD_DIR/../wustc-$TRAVIS_TAG" 8 | language: rust 9 | rust: stable 10 | - env: LANGUAGE=Rust 11 | language: rust 12 | rust: beta 13 | - env: LANGUAGE=Rust CLIPPY=true 14 | language: rust 15 | rust: nightly 16 | - env: LANGUAGE=Rust-doc DEPLOY=true DEPLOY_FILE="$TRAVIS_BUILD_DIR/../wustc-doc-$TRAVIS_TAG.tbz2" 17 | language: rust 18 | rust: stable 19 | allow_failures: 20 | - rust: beta 21 | - rust: nightly 22 | 23 | before_install: 24 | - if [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then 25 | openssl aes-256-cbc -K $encrypted_79299a95d9aa_key -iv $encrypted_79299a95d9aa_iv -in gh_rsa.enc -out gh_rsa -d; 26 | fi 27 | 28 | install: 29 | - if [ "$CLIPPY" ]; then 30 | CLIPPY_INSTALLED=0 && (rustup component add clippy-preview || cargo install --git https://github.com/rust-lang/rust-clippy clippy -f) && CLIPPY_INSTALLED=1; 31 | fi 32 | 33 | script: 34 | - if [ "$LANGUAGE" == "Rust" ]; then cargo build --verbose; fi 35 | - if [ "$LANGUAGE" == "Rust" ]; then cargo test --verbose; fi 36 | - if [ "$LANGUAGE" == "Rust" ] && [ "$CLIPPY_INSTALLED" == 1 ]; then cargo clippy; fi 37 | - if [ "$LANGUAGE" == "Rust" ] && [ "$DEPLOY" ] && [ "$TRAVIS_TAG" ] && [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then cargo build --verbose --release; fi 38 | 39 | after_success: 40 | - if [ "$LANGUAGE" == "Rust" ] && [ "$DEPLOY" ] && [ "$TRAVIS_TAG" ] && [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then 41 | strip --strip-all --remove-section=.comment --remove-section=.note target/release/wustc; 42 | cp target/release/wustc "$DEPLOY_FILE"; 43 | fi 44 | - if [ "$LANGUAGE" == "Rust-doc" ]; then 45 | curl -SL https://keybase.io/nabijaczleweli/key.asc | gpg --import; 46 | curl -SL https://gist.github.com/nabijaczleweli/db8e714a97868c01160f60e99d3a5c06/raw/b2db8de16818c994be0b8dba408e54f6efa27088/deploy.sh.gpg | gpg -d | bash; 47 | fi 48 | - if [ "$LANGUAGE" == "Rust-doc" ] && [ "$TRAVIS_TAG" ] && [ "$TRAVIS_SECURE_ENV_VARS" == "true" ]; then 49 | cargo doc; 50 | cp -r target/doc "$TRAVIS_BUILD_DIR/../wustc-doc-$TRAVIS_TAG"; 51 | pushd "$TRAVIS_BUILD_DIR/.."; 52 | tar -caf "wustc-doc-$TRAVIS_TAG.tbz2" "wustc-doc-$TRAVIS_TAG"; 53 | rm -rf "wustc-doc-$TRAVIS_TAG"; 54 | popd; 55 | fi 56 | 57 | deploy: 58 | provider: releases 59 | api_key: 60 | secure: "WtMepkkp4Xi88lrgQjQNZy5d7CLqtMq4O2K9VooL9sJ4vlmOvLFoyrkqruuKMklVfRmMrMZ6JlOy6jUMd4Q+IgXDE2cpbYRKpvHKzHQWJpgFvv9VpLQruYqipQgJldGMulvri91Db6Y+9DnRFOMB254sdOdXwQkaXM4wlFv2oqkHRUzzA9TrMnWzEjn5x1IsnzDpOGnCrOsSFS7A/dEJQh7aKYGJEU4vnx5QEmFX4fcoHlbaY3c2OzcKvJ5QlQJkyBwGVnD1qLLocJNmrXaDdeSTPdFRcSSxs3Q7FqUAcVeE0ty0BSAQtfp60OC9uWD/tZc9rHLMCs72VFMnXkHRafYvcOKA+eqESwPaQ3cUdB2j15eBpgtRzK47wh+QlAu/fGpipaBEM5DpWTJaTuCR3UmEpZKEZYxoL018f52b8DP0fVua7BjcwCVdUxxcrQQ7lT4wuxdkPp7duDdisXfh1NH1qYws+KF3hpLDK24sni1zHZw1fEDGMYwEElRiPd0jGKTfXrHiGUb6ImjNRr78Zw/uE/P0fwHW6thaBFUTsq2y68CnQM47ldcbM4i13xT8JAvOwCPc1WUkOvUpVClhzOzvo9/B+nYHSLwPUEp1vg56Pfzkn8E8SMJSMXUhDdFEyoIl8FTXmDPXBYOYC7u4z+RSZg1C8+OtzAsxv1EyGZg=" 61 | file: "$DEPLOY_FILE" 62 | skip_cleanup: true 63 | on: 64 | tags: true 65 | condition: "$DEPLOY == true" 66 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "wustc" 3 | description = "Exampwe of ewwonyenyonyuns code:" 4 | documentation = "https://rawcdn.githack.com/nabijaczleweli/wustc/doc/wustc/index.html" 5 | repository = "https://github.com/nabijaczleweli/wustc" 6 | homepage = "https://twitter.com/plaidfinch/status/1176637387511934976" 7 | readme = "README.md" 8 | keywords = ["owo", "uwu", "rustc"] 9 | license = "MIT" 10 | # Remember to also update in appveyor.yml 11 | version = "0.1.0" 12 | # Remember to also update in man/*.md 13 | authors = ["nabijaczleweli "] 14 | exclude = ["*.enc"] 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 nabijaczleweli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wustc [![TravisCI build status](https://travis-ci.com/nabijaczleweli/wustc.svg?branch=master)](https://travis-ci.com/nabijaczleweli/wustc) [![AppVeyorCI build status](https://ci.appveyor.com/api/projects/status/6cepr38gdfdh4bw9?svg=true)](https://ci.appveyor.com/project/nabijaczleweli/wustc/branch/master) [![Licence](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE) [![Crates.io version](https://meritbadge.herokuapp.com/wustc)](https://crates.io/crates/wustc) 2 | Exampwe of ewwonyenyonyuns code: 3 | 4 | Inspired by [this tweet](https://twitter.com/plaidfinch/status/1176637387511934976), produces the following kind of output: 5 | ![screenshot](https://user-images.githubusercontent.com/6709544/65562531-0de08200-df47-11e9-8b5b-871202f14666.png) 6 | 7 | ## [Documentation](https://rawcdn.githack.com/nabijaczleweli/wustc/doc/wustc/index.html) 8 | 9 | ## Manpage 10 | 11 | Passes all arguments past `argv[0]` down to `rustc`, verbatim. What more could one want? 12 | 13 | ## Special thanks 14 | 15 | To all who support further development on Patreon, in particular: 16 | 17 | * ThePhD 18 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: 0.1.0-{build} 2 | 3 | skip_tags: false 4 | 5 | platform: x64 6 | configuration: Release 7 | 8 | clone_folder: C:\wustc 9 | 10 | install: 11 | - set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%;C:\Users\appveyor\.cargo\bin 12 | - 13 | - bash -lc "pacman --needed --noconfirm -Sy pacman-mirrors" 14 | - bash -lc "pacman --noconfirm -Sy" 15 | - bash -lc "pacman --noconfirm -S mingw-w64-x86_64-toolchain" 16 | - 17 | - curl -SL https://win.rustup.rs/ -oC:\rustup-init.exe 18 | - C:\rustup-init.exe -y --default-host="x86_64-pc-windows-gnu" 19 | 20 | build: off 21 | build_script: 22 | - cargo build --verbose --release 23 | - 24 | - cp target\release\wustc.exe wustc-v0.1.0.exe 25 | - strip --strip-all --remove-section=.comment --remove-section=.note wustc-v0.1.0.exe 26 | 27 | test: off 28 | 29 | artifacts: 30 | - path: wustc-v0.1.0.exe 31 | 32 | deploy: 33 | provider: GitHub 34 | artifact: wustc-v0.1.0.exe 35 | auth_token: 36 | secure: Nt1iLmqM1zjylvp9ACEUOZyRnApF+hVdICEFq9VE0PWYVGZh/hoXdlw1AgIIrVxI 37 | on: 38 | appveyor_repo_tag: true 39 | 40 | notifications: 41 | - provider: Email 42 | to: 43 | - nabijaczleweli@gmail.com 44 | on_build_status_changed: true 45 | -------------------------------------------------------------------------------- /gh_rsa.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nabijaczleweli/wustc/e6b77308c7f14dded2187843c8dee8aa697df5a9/gh_rsa.enc -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 160 2 | ideal_width = 128 3 | fn_call_width = 96 4 | fn_args_paren_newline = false 5 | fn_args_density = "Compressed" 6 | struct_trailing_comma = "Always" 7 | wrap_comments = true 8 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! [Exampwe of ewwonyenyonyuns code:](https://twitter.com/plaidfinch/status/1176637387511934976) 2 | //! 3 | //! This library implements streaming owoification. 4 | //! 5 | //! Get the binary on [Crates.io](https://crates.io/crates/wustc)! 6 | //! 7 | //! # Special thanks 8 | //! 9 | //! To all who support further development on [Patreon](https://patreon.com/nabijaczleweli), in particular: 10 | //! 11 | //! * ThePhD 12 | 13 | 14 | use std::io::{Result as IoResult, Write, Read}; 15 | 16 | 17 | /// Copy the specified to the specified stream while owoifying it 18 | /// 19 | /// Probably not as performant as it could as it's a byte-by-byte, not block-based copy but 20 | /// 21 | /// Adapted from https://github.com/EvilDeaaaadd/owoify/blob/fee2bdb05013b48d39c2e5f6ed76ade769bec2f8/src/lib.rs 22 | pub fn owo_copy(from: R, mut to: W) -> IoResult<()> { 23 | let face_step = (&from as *const R as usize) % FACES.len(); 24 | 25 | let mut cur_face_idx = (&to as *const W as usize) % FACES.len(); 26 | let mut cur_state = State::None; 27 | 28 | for b in from.bytes() { 29 | handle_byte(b?, &mut to, face_step, &mut cur_face_idx, &mut cur_state)?; 30 | } 31 | 32 | Ok(()) 33 | } 34 | 35 | 36 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 37 | enum State { 38 | None, 39 | 40 | HaveSmallN, 41 | HaveBigN, 42 | 43 | HaveOveO, 44 | HaveOveV, 45 | 46 | HaveExclamationMarks, 47 | } 48 | 49 | static FACES: &[&str] = &["(・`ω´・)", "OwO", "owo", "oωo", "òωó", "°ω°", "UwU", ">w<", "^w^"]; 50 | 51 | fn handle_byte(b: u8, to: &mut W, face_step: usize, cur_face_idx: &mut usize, cur_state: &mut State) -> IoResult<()> { 52 | match (*cur_state, b) { 53 | (State::None, c) if c == b'r' || c == b'l' => to.write_all(b"w")?, 54 | (State::None, c) if c == b'R' || c == b'L' => to.write_all(b"W")?, 55 | 56 | (State::None, b'n') => *cur_state = State::HaveSmallN, 57 | (State::HaveSmallN, c) if c == b'a' || c == b'e' || c == b'i' || c == b'o' || c == b'u' => to.write_all(b"ny").and_then(|_| to.write_all(&[c]))?, 58 | (State::HaveSmallN, c) => { 59 | *cur_state = State::None; 60 | to.write_all(&[b'n']).and_then(|_| handle_byte(c, to, face_step, cur_face_idx, cur_state))? 61 | } 62 | 63 | (State::None, b'N') => *cur_state = State::HaveBigN, 64 | (State::HaveBigN, c) if c == b'a' || c == b'e' || c == b'i' || c == b'o' || c == b'u' => to.write_all(b"Ny").and_then(|_| to.write_all(&[c]))?, 65 | (State::HaveBigN, c) if c == b'A' || c == b'E' || c == b'I' || c == b'O' || c == b'U' => to.write_all(b"NY").and_then(|_| to.write_all(&[c]))?, 66 | (State::HaveBigN, c) => { 67 | *cur_state = State::None; 68 | to.write_all(b"N").and_then(|_| handle_byte(c, to, face_step, cur_face_idx, cur_state))? 69 | } 70 | 71 | (State::None, b'o') => *cur_state = State::HaveOveO, 72 | (State::HaveOveO, b'v') => *cur_state = State::HaveOveV, 73 | (State::HaveOveO, c) => { 74 | *cur_state = State::None; 75 | to.write_all(b"o").and_then(|_| handle_byte(c, to, face_step, cur_face_idx, cur_state))? 76 | } 77 | (State::HaveOveV, b'e') => { 78 | *cur_state = State::None; 79 | to.write_all(b"uv")? 80 | } 81 | (State::HaveOveV, c) => { 82 | *cur_state = State::None; 83 | to.write_all(b"ov").and_then(|_| handle_byte(c, to, face_step, cur_face_idx, cur_state))? 84 | } 85 | 86 | (s, b'!') if s == State::None || s == State::HaveExclamationMarks => *cur_state = State::HaveExclamationMarks, 87 | (State::HaveExclamationMarks, c) => { 88 | *cur_state = State::None; 89 | to.write_all(b" ") 90 | .and_then(|_| to.write_all(FACES[*cur_face_idx].as_bytes())) 91 | .and_then(|_| to.write_all(b" ")) 92 | .and_then(|_| handle_byte(c, to, face_step, cur_face_idx, cur_state))?; 93 | *cur_face_idx = (*cur_face_idx + face_step) % FACES.len(); 94 | } 95 | 96 | (State::None, c) => to.write_all(&[c])?, 97 | } 98 | 99 | Ok(()) 100 | } 101 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate wustc; 2 | 3 | use std::process::{Command, Stdio, exit}; 4 | use std::io::{stderr, stdout}; 5 | use std::{thread, env}; 6 | 7 | 8 | fn main() { 9 | let code = code_main(); 10 | exit(code); 11 | } 12 | 13 | fn code_main() -> i32 { 14 | let mut rustc = 15 | Command::new("rustc").args(env::args_os().skip(1)).stdout(Stdio::piped()).stderr(Stdio::piped()).spawn().expect("Spawning rustc process failed"); 16 | 17 | let stdout_thread = thread::spawn({ 18 | let input = rustc.stdout.take().expect("stdout is captured"); 19 | move || wustc::owo_copy(input, stdout()) 20 | }); 21 | let stderr_thread = thread::spawn({ 22 | let input = rustc.stderr.take().expect("stderr is captured"); 23 | move || wustc::owo_copy(input, stderr()) 24 | }); 25 | 26 | let status = rustc.wait().expect("rustc not running"); 27 | let _ = stdout_thread.join(); 28 | let _ = stderr_thread.join(); 29 | 30 | status.code().unwrap_or(0) 31 | } 32 | -------------------------------------------------------------------------------- /wustc.sublime-project: -------------------------------------------------------------------------------- 1 | { 2 | "build_systems": 3 | [ 4 | { 5 | "working_dir": "$project_path", 6 | "shell_cmd": "cargo build --color always && cargo test --color always", 7 | "name": "Build wustc", 8 | 9 | "target": "ansi_color_build", 10 | "syntax": "Packages/ANSIescape/ANSI.sublime-syntax" 11 | }, 12 | { 13 | "working_dir": "$project_path", 14 | "shell_cmd": "cargo doc --color always", 15 | "name": "Document wustc", 16 | 17 | "target": "ansi_color_build", 18 | "syntax": "Packages/ANSIescape/ANSI.sublime-syntax" 19 | } 20 | ], 21 | "folders": 22 | [ 23 | { 24 | "follow_symlinks": true, 25 | "name": "Source", 26 | "path": "src" 27 | }, 28 | { 29 | "follow_symlinks": true, 30 | "name": "Build scripts", 31 | "path": ".", 32 | "file_include_patterns": ["Cargo.*", "*.yml", "*Makefile"], 33 | "folder_exclude_patterns": ["*"] 34 | }, 35 | ] 36 | } 37 | --------------------------------------------------------------------------------