1 stable release
1.0.0 | May 26, 2021 |
---|
#392 in Visualization
49KB
712 lines
Multi-Dimensional Analog Literals in Rust
Inspired by the abhorrent incredible
Multi-Dimensional Analog Literals
library created by Eelis back in 2006, I am proud to present
analog_literal!
- a Rust macro that enables embedding analog literals
directly into Rust code.
Just take a look at this incredible set of features!
- Support for every physical dimension from 0 to N (for all N <= 3)!
- Strict syntax checking - no mismatched widths, lengths, or heights!
- Entirely safe Rust, enforced by
#[deny(unsafe_code)]
! - Entirely
const
evaluatable - use analog literals in anyconst
context! #![no_std]
by default, without relying onalloc
!- Dependency Free!
- Open source under a very permissive license!
- Made with love, passion, and a disregard of all things holy!
Modes of Operation
The single analog_literal!
macro can be used to define 3 different kinds
of analog literals: a 1D line, a 2D rectangle, and a 3D cuboid.
1D Lines
A 1D analog literal (known in professional circles as a "line") is perfect for all those times when you wanted to self-document just how big (or small!) a scalar was.
Defining them works exactly as you'd expect:
let mine = analog_literal! { +--------------------+ };
let yours = analog_literal! { +----------+ };
assert!(mine > yours);
1D analog literals can also be defined using alternative I
terminators,
for that classic 3rd grade math class feeling:
assert_eq!(
analog_literal! { I----I }
+ analog_literal! { I------I },
/* ---------------------------------------------- */
analog_literal! { I----------I },
);
Heck, you can even use them inline in const
contexts to quickly and easy
visualize just how large of an array you're allocating!
let buf = [0; analog_literal!{ +--------------------------------+ }];
Educational!
2D Rectangles
While there are plenty of Rust libraries out there trying to provide a elegant, cross-platform solution to writing GUIs, not a single one has a good way of visually representing the GUI that the code is trying to represent.
Well, with a bit of help from 2D analog literals (sometimes referred to by seasoned mathematicians as "rectangles"), these libraries can be turbocharged with true WYSIWYG capabilities!
const MODAL_POPUP: Rectangle = analog_literal! {
+----------------------------------------------------------+
| |
| /*----------------------------------------*/ |
| /* Do you accept the terms and conditions */ |
| /* and agree to sell your eternal soul to */ |
| /* the dark lord beelzebub? */ |
| /*----------------------------------------*/ |
| |
| /* Yes */ /* Also Yes */ |
| |
+----------------------------------------------------------+
};
assert_eq!(MODAL_POPUP.w, 29);
assert_eq!(MODAL_POPUP.h, 9);
assert_eq!(MODAL_POPUP.area(), 261);
The possibilities are endless!
3D Cuboids
Say you're trying to solve the packing problem for fitting the largest number of dogecoin mining rigs in your 1.5 bedroom SF "apartment". A 1x programmer would probably just use a couple of boring 'ol cOnStAnTs to define the length, width, and height of their dogecoin miners. Of course, you're not a 1x programmer, you're a 10x programmer, so you use a 3D analog literal (colloquially referred to as a "cuboid") to visually represent the dimensions of your mining rigs:
const MINING_RIG: Cuboid = analog_literal! {
+------------------------------------------+
/ /|
/ / +
/ /**/ / /
/ /**/ / /
/ /**/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
/ / /
+------------------------------------------+ /
| /* -= dogecoin-one =- */ /*(o)*/ |/
+------------------------------------------+
};
assert_eq!(MINING_RIG.w, 21);
assert_eq!(MINING_RIG.h, 1);
assert_eq!(MINING_RIG.l, 16);
assert_eq!(MINING_RIG.volume(), 336);
Oh yeah, I can taste those DOGE tendies already!
Putting it all together
Brace yourself, because the following example may very well shake you to the core:
use analog_literals::analog_literal as al;
al! {
+----------+
/ /|
/ / |
/ / +
/ / /
+----------+ /
| | /
| |/
+----------+ }.volume() == al! { +----+
| |
| |
| |
| |
| |
+----+ }.area() * al! { +--------+ }
Safety and Syntax Validation
In true Rust fashion, this library strives to be as safe as can be. Not only
is it 100% unsafe code free (enforced by #![deny(unsafe_code)]
in the
crate root), but it will also catch any malformed analog literals at compile
time!
I'm sure we've all been in this situation: it's 4:55 on a weekday, you're desperate for another cup of coffee, and you really feel like just packing it in early. You decide to call it for the day, and leave yourself a comment to pick up where you left off tomorrow...
const YET_ANOTHER_RECT: Rectangle = analog_literal! {
+----------------+
| |
| |
+------------+ // TODO: type more `--`...
};
You come back in the next morning, and without thinking, you decide to check in what you had from yesterday into prod. But it's okay, because as the CI runs on your shoddy code from the day before, the Rust compiler helpfully spits out a compilation error!
error[E0080]: evaluation of constant value failed
--> src/lib.rs:364:37
|
5 | const YET_ANOTHER_RECT: Rectangle = analog_literal! {
| _____________________________________^
6 | | +----------------+
7 | | | |
8 | | | |
9 | | +------------+ // TODO: type more `--`...
10 | | };
| |_^ attempt to compute `0_usize - 1_usize`, which would overflow
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Look, I never said the error messages would be descriptive, okay...
But hey, would you look at that! With analog_literal!
, you can rest easy
knowing that your literals are guaranteed to be well formed From Top to
Bottom, and Left to Right™
So what are you waiting for! Go ahead and add analog_literals
to your
project today!
[dependencies]
analog_literals = "*"
Final Comments
I'm not gonna lie - I was already half-way done implementing 3D literals before I'd even thought to check if anyone else had done something as stupid as this already. Lo and behold, jswrenn/analit beat me to the punch by a whopping 6 years!
A smarter man might have stopped working on his shoddy rewrite and scrapped his shoddy POC then and there. Instead, stubborn as I am, I decided to push forward and spent another handful of hours polishing it up, adding syntax validation, and writing a whole mess of docs.
Do I regret it? Ehh, maybe.
It is funny tho? I mean, I think so.
Oh, and lastly: please, please don't use this library in an actual project.
If I saw something like this while perusing a crate's source code, I'd
probably nope the heck out of there, turn off my computer, and go on a long
walk to contemplate what kind of life choices could have led someone to
thinking that including analog_literals
in their project would be a good
idea.