├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "memchr" 5 | version = "2.2.1" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | 8 | [[package]] 9 | name = "nom" 10 | version = "4.2.3" 11 | source = "registry+https://github.com/rust-lang/crates.io-index" 12 | dependencies = [ 13 | "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 15 | ] 16 | 17 | [[package]] 18 | name = "tnfilt" 19 | version = "0.1.1" 20 | dependencies = [ 21 | "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", 22 | ] 23 | 24 | [[package]] 25 | name = "version_check" 26 | version = "0.1.5" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | 29 | [metadata] 30 | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 31 | "checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" 32 | "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" 33 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tnfilt" 3 | version = "0.1.1" 4 | authors = ["Russell Mull "] 5 | edition = "2018" 6 | readme = "README.md" 7 | description = "Turn typenum compilation error messages into something fit for a human" 8 | repository = "https://github.com/auxoncorp/tnfilt" 9 | license-file = "LICENSE" 10 | 11 | [dependencies] 12 | nom = "4.2.3" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Auxon Corporation 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tnfilt 2 | 3 | ## Overview 4 | 5 | Turn your typenum compilation errors into something fit for a 6 | human. `tnfilt` turns this: 7 | 8 | ``` 9 | error[E0271]: type mismatch resolving `, typenum::B0>, typenum::B1>, typenum::B0>, typenum::B0> as typenum::IsLessOrEqual, typenum::B0>, typenum::B1>, typenum::B0>>>::Output == typenum::B1` 10 | ``` 11 | 12 | into this: 13 | ``` 14 | error[E0271]: type mismatch resolving `>::Output == typenum::B1` 15 | ``` 16 | 17 | ## Getting Started 18 | ```shell 19 | $ cargo install --git ssh://git@github.com/auxoncorp/tnfilt.git --force 20 | ``` 21 | 22 | ## Usage 23 | ```shell 24 | $ cargo build 2>&1 | tnfilt 25 | ``` 26 | 27 | ## License 28 | 29 | `tnfilt` is licensed under the MIT License (MIT) unless otherwise 30 | noted. Please see [LICENSE](./LICENSE) for more details. 31 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate nom; 2 | use nom::*; 3 | use std::io::{self, BufRead}; 4 | 5 | #[derive(Debug)] 6 | enum Bit { 7 | B0, 8 | B1, 9 | } 10 | 11 | impl Bit { 12 | fn val(&self) -> u32 { 13 | match self { 14 | Bit::B0 => 0, 15 | Bit::B1 => 1, 16 | } 17 | } 18 | } 19 | 20 | #[derive(Debug)] 21 | enum Unsigned { 22 | UTerm, 23 | UInt(Box, Bit), 24 | } 25 | 26 | impl Unsigned { 27 | fn from_tuple((us, b): (Unsigned, Bit)) -> Unsigned { 28 | Unsigned::UInt(Box::new(us), b) 29 | } 30 | 31 | fn as_u32(&self) -> u32 { 32 | match self { 33 | Unsigned::UTerm => 0, 34 | Unsigned::UInt(inner, bit) => (inner.as_u32() << 1) | bit.val(), 35 | } 36 | } 37 | } 38 | 39 | #[derive(Debug)] 40 | enum Term { 41 | Unsigned(Unsigned), 42 | Char(char), 43 | } 44 | 45 | named!(bit<&str, Bit>, 46 | preceded!( 47 | alt_complete!(tag!("typenum::B") | tag!("typenum::bit::B")), 48 | alt!( 49 | value!(Bit::B0, tag!("0")) | value!(Bit::B1, tag!("1")) 50 | ) 51 | ) 52 | ); 53 | 54 | named!(unsigned<&str, Unsigned>, 55 | alt!( 56 | value!(Unsigned::UTerm, 57 | alt_complete!(tag!("typenum::UTerm") | tag!("typenum::uint::UTerm"))) 58 | | 59 | delimited!( 60 | alt_complete!(tag!("typenum::UInt<") | tag!("typenum::uint::UInt<")), 61 | map!( 62 | separated_pair!(unsigned, tag!(", "), bit), 63 | Unsigned::from_tuple 64 | ), 65 | tag!(">") 66 | ) 67 | ) 68 | ); 69 | 70 | named!(line<&str, Vec >, 71 | many0!( 72 | alt_complete!( 73 | map!(unsigned, Term::Unsigned) | map!(anychar, Term::Char) 74 | ) 75 | ) 76 | ); 77 | 78 | fn main() { 79 | for l in io::stdin().lock().lines().map(|l| l.unwrap()) { 80 | for term in line(&l).unwrap().1 { 81 | match term { 82 | Term::Char(c) => print!("{}", c), 83 | Term::Unsigned(u) => print!("U{}", u.as_u32()), 84 | } 85 | } 86 | println!(""); 87 | } 88 | } 89 | --------------------------------------------------------------------------------