├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md └── src └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "analit" 3 | version = "0.1.0" 4 | authors = ["John Wrenn "] 5 | 6 | description = "Add another dimension to your Rust project with analog geometric literals." 7 | repository = "https://github.com/jswrenn/analit" 8 | keywords = ["analog","geometry","2D","3D"] 9 | license = "MIT" 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 John Wrenn 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Analit: Analog Literals for Rust 2 | For all of Rust's great improvements on the status quo of systems languages, one feature has been sorely missing. No, it's not higher-kinded-types, or integer generics, or having a name that includes the letter 'C'. It's analog literals. Ever since Eelis debuted "Analog Literals" in 2005 [as a C++ utility](http://www.eelis.net/C++/analogliterals.xhtml), the ability to draw geometry out using ASCII art has set a new bar for what constitutes a minimal-viable-language. 3 | 4 | ## Examples 5 | Analog literals follow a simple syntactic pattern. The pointy corners of things are marked by '+' characters, one unit in the x-axis is represented by '--', and one unit in the Y and Z axes are represented by '|' and '/', respectively. The reason two characters are used to represent just one unit in the x-axis is to compensate for the rectangular shape that characters are rendered with. Analog expressions return a tuple reflecting the dimensions of the drawing. But enough talk--let's see some examples: 6 | 7 | ### One-Dimensional 8 | A line of length two along the X axis: 9 | ```rust 10 | assert_eq!(2, analit!( 11 | +----+ 12 | )); 13 | ``` 14 | 15 | A line of length two along the Y axis: 16 | ```rust 17 | assert_eq!(2, analit!( 18 | + 19 | | 20 | | 21 | + 22 | )); 23 | ``` 24 | 25 | A line of length two along the Z axis: 26 | ```rust 27 | assert_eq!(2,analit!( 28 | + 29 | / 30 | / 31 | + 32 | )); 33 | ``` 34 | 35 | ### Two-Dimensional 36 | Two dimensional literals have proven themselves especially valuable to GUI programmers. 37 | 38 | A (2,1) rectangle defined across X and Y: 39 | ```rust 40 | assert_eq!((2,1),analit!( 41 | +----+ 42 | | | 43 | +----+ 44 | )); 45 | ``` 46 | 47 | ...across X and Z: 48 | ```rust 49 | assert_eq!((2,1),analit!( 50 | +----+ 51 | / / 52 | +----+ 53 | )); 54 | ``` 55 | 56 | ...across Y and Z: 57 | ```rust 58 | assert_eq!((2,1),analit!( 59 | + 60 | /| 61 | / + 62 | + / 63 | |/ 64 | + 65 | )); 66 | ``` 67 | 68 | ### Three-Dimensional 69 | It's time to dig those red-and-blue glasses out from between the couch cushions; we're going into the next dimension! 70 | ```rust 71 | assert_eq!((1,1,3),analit!( 72 | +--+ 73 | / /| 74 | / / + 75 | / / / 76 | +--+ / 77 | | |/ 78 | +--+ 79 | )); 80 | ``` 81 | It's like it's coming right out of the screen! 82 | 83 | ## Using Analog Literals in Your Next Project* 84 | Simply add the following to your `Cargo.toml` 85 | 86 | ```toml 87 | [dependencies.analit] 88 | git = "https://github.com/jswrenn/analit" 89 | ``` 90 | 91 | Or, from the registry: 92 | ```toml 93 | [dependencies] 94 | analit = "*" 95 | ``` 96 | *Please don't. 97 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #[macro_export] 2 | macro_rules! analit ( 3 | ( +-- $($t:tt)+) => (analit!(X 1 , , ;$($t)+)); 4 | (X $x:expr, , ; -- $($t:tt)+) => (analit!(X $x+1, , ;$($t)+)); 5 | (X $x:expr, , ; + ) => (($x)); 6 | 7 | 8 | ( +| $($t:tt)+) => (analit!(Y 1 , , ;$($t)+)); 9 | (Y $x:expr, , ; | $($t:tt)+) => (analit!(Y $x+1, , ;$($t)+)); 10 | (Y $x:expr, , ; + ) => (($x)); 11 | 12 | 13 | ( +/ $($t:tt)+) => (analit!(Z 1 , , ;$($t)+)); 14 | (Z $x:expr, , ; / $($t:tt)+) => (analit!(Z $x+1, , ;$($t)+)); 15 | (Z $x:expr, , ; + ) => (($x)); 16 | 17 | 18 | (X $x:expr, , ; +/ $($t:tt)+) => (analit!(XZ $x ,1 , ;$($t)+)); 19 | (XZ $x:expr,$y:expr, ; / $($t:tt)+) => (analit!(XZ $x ,$y+1, ;$($t)+)); 20 | (XZ $x:expr,$y:expr, ; + $($t:tt)+) => (($x,$y/2)); 21 | 22 | 23 | (X $x:expr, , ; +| $($t:tt)+) => (analit!(XY $x ,1 , ;$($t)+)); 24 | (XY $x:expr,$y:expr, ; | $($t:tt)+) => (analit!(XY $x ,$y+1, ;$($t)+)); 25 | (XY $x:expr,$y:expr, ; +- $($t:tt)+) => (($x,$y/2)); 26 | 27 | 28 | (Z $x:expr, , ; | $($t:tt)+) => (analit!(YZ $x ,1 , ;$($t)+)); 29 | (YZ $x:expr,$y:expr, ; | $($t:tt)+) => (analit!(YZ $x ,$y+1, ;$($t)+)); 30 | (YZ $x:expr,$y:expr, ; / $($t:tt)+) => (analit!(YZ $x+1,$y , ;$($t)+)); 31 | (YZ $x:expr,$y:expr, ; + $($t:tt)+) => (analit!(YZ $x ,$y , ;$($t)+)); 32 | (YZ $x:expr,$y:expr, ; + ) => (($x/2,$y/2)); 33 | 34 | 35 | (XZ $x:expr,$y:expr, ; | $($t:tt)+) => (analit!(XYZ $x ,1 ,$y*2;$($t)+)); 36 | (XYZ $x:expr,$y:expr,$z:expr; | $($t:tt)+) => (analit!(XYZ $x ,$y+1,$z ;$($t)+)); 37 | (XYZ $x:expr,$y:expr,$z:expr; / $($t:tt)+) => (analit!(XYZ $x ,$y ,$z+1;$($t)+)); 38 | (XYZ $x:expr,$y:expr,$z:expr; - $($t:tt)+) => (analit!(XYZ $x ,$y ,$z ;$($t)+)); 39 | (XYZ $x:expr,$y:expr,$z:expr; + $($t:tt)+) => (analit!(XYZ $x ,$y ,$z ;$($t)+)); 40 | (XYZ $x:expr,$y:expr,$z:expr; + ) => (($x, $y/3, $z/3)); 41 | 42 | ); 43 | 44 | #[test] 45 | fn one_dimension() { 46 | assert_eq!(2, analit!( 47 | +----+ 48 | )); 49 | 50 | assert_eq!(2, analit!( 51 | + 52 | | 53 | | 54 | + 55 | )); 56 | 57 | assert_eq!(2,analit!( 58 | + 59 | / 60 | / 61 | + 62 | )); 63 | } 64 | 65 | #[test] 66 | fn two_dimensional() { 67 | 68 | assert_eq!((2,1),analit!( 69 | +----+ 70 | | | 71 | +----+ 72 | )); 73 | 74 | 75 | assert_eq!((2,1),analit!( 76 | +----+ 77 | / / 78 | +----+ 79 | )); 80 | 81 | assert_eq!((2,1),analit!( 82 | + 83 | /| 84 | / + 85 | + / 86 | |/ 87 | + 88 | )); 89 | 90 | assert_eq!((1,1),analit!( 91 | + 92 | /| 93 | + + 94 | |/ 95 | + 96 | )); 97 | 98 | assert_eq!((1,2),analit!( 99 | + 100 | /| 101 | + | 102 | | + 103 | |/ 104 | + 105 | )); 106 | } 107 | 108 | #[test] 109 | fn three_dimensional() { 110 | 111 | assert_eq!((1,1,3),analit!( 112 | +--+ 113 | / /| 114 | / / + 115 | / / / 116 | +--+ / 117 | | |/ 118 | +--+ 119 | )); 120 | 121 | assert_eq!((4,1,1),analit!( 122 | +--------+ 123 | / /| 124 | +--------+ + 125 | | |/ 126 | +--------+ 127 | )); 128 | 129 | } 130 | 131 | --------------------------------------------------------------------------------