This commit is contained in:
Freya Murphy 2023-06-08 00:55:42 -04:00
commit 2dad06cae3
6 changed files with 172 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

16
Cargo.lock generated Normal file
View file

@ -0,0 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "libc"
version = "0.2.146"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b"
[[package]]
name = "urine"
version = "0.1.0"
dependencies = [
"libc",
]

9
Cargo.toml Normal file
View file

@ -0,0 +1,9 @@
[package]
name = "urine"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libc = "0.2.146"

17
src/error.rs Normal file
View file

@ -0,0 +1,17 @@
use std::fmt::{Result, Display, Formatter};
pub enum PissError {
InvalidSuffix(String),
InvalidNumber(String),
NumberNotPositive
}
impl Display for PissError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
match self {
Self::InvalidSuffix(s) => write!(f, "I cannot piss the suffix {s:?}"),
Self::InvalidNumber(s) => write!(f, "I cannot piss the invalid number {s:?}"),
Self::NumberNotPositive => write!(f, "I cannot piss nonexistent memory")
}
}
}

58
src/lib.rs Normal file
View file

@ -0,0 +1,58 @@
use std::cell::RefCell;
use libc::malloc;
pub mod error;
pub mod parse;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
pub struct PissAmount {
to_piss: u128
}
#[derive(Copy, Clone, Debug)]
pub enum Toliet {
Rust,
Lazy,
Unsafe
}
fn leak_rust(amount: usize) {
Vec::<u8>::with_capacity(amount).leak();
}
thread_local!(static TOLIET: RefCell<Vec<Vec<u8>>> = RefCell::new(Vec::new()));
fn leak_lazy(amount: usize) {
TOLIET.with(|t| {
t.borrow_mut().push(Vec::<u8>::with_capacity(amount));
})
}
fn leak_unsafe(amount: usize) {
unsafe {
malloc(amount);
}
}
fn leak_match(amount: usize, method: Toliet) {
match method {
Toliet::Rust => leak_rust(amount),
Toliet::Lazy => leak_lazy(amount),
Toliet::Unsafe => leak_unsafe(amount),
}
}
pub fn leak<T: Into<PissAmount>>(amount: T, method: Toliet) {
let num: u128 = amount.into().to_piss;
let count = num / usize::MAX as u128;
for _ in 0..count {
leak_match(usize::MAX, method);
}
leak_match((num % usize::MAX as u128) as usize, method);
}
pub async fn leak_async<T: Into<PissAmount>>(amount: T, method: Toliet) {
leak(amount, method);
}

71
src/parse.rs Normal file
View file

@ -0,0 +1,71 @@
use std::str::FromStr;
use crate::{error::PissError, PissAmount};
impl<T> From<T> for PissAmount
where T: Into<u128> {
fn from(num: T) -> PissAmount {
PissAmount {
to_piss: num.into()
}
}
}
fn parse_suffix(s: &str) -> Result<u128, PissError> {
Ok(match s { // nepal
"k" | "kb" => 1_000,
"m" | "mb" => 1_000_000,
"g" | "gb" => 1_000_000_000,
"t" | "tb" => 1_000_000_000_000,
"p" | "pb" => 1_000_000_000_000_000,
"e" | "eb" => 1_000_000_000_000_000_000,
"x" | "xb" => 1_000_000_000_000_000_000_000,
"y" | "yb" => 1_000_000_000_000_000_000_000_000,
"r" | "rb" => 1_000_000_000_000_000_000_000_000_000,
"q" | "qb" => 1_000_000_000_000_000_000_000_000_000_000,
"ki" | "kib" => 0x400,
"mi" | "mib" => 0x100000,
"gi" | "gib" => 0x40000000,
"ti" | "tib" => 0x10000000000,
"pi" | "pib" => 0x4000000000000,
"ei" | "eib" => 0x1000000000000000,
"xi" | "xib" => 0x400000000000000000,
"yi" | "yib" => 0x100000000000000000000,
"ri" | "rib" => 0x40000000000000000000000,
"qi" | "qib" => 0x10000000000000000000000000,
"" | "b" => 1, // uwu
_ => return Err(PissError::InvalidSuffix(s.into())) // such nepal
})
}
fn parse_file_size(s: &str) -> Result<PissAmount, PissError> {
let mut end = 0;
for (i, c) in s.char_indices() {
if c.is_digit(10) || c == '.' { continue; }
end = i;
break;
}
let num_text = &s[..end];
let suffix_text = &s[end..];
let Ok(num) = num_text.parse::<f64>() else {
return Err(PissError::InvalidNumber(num_text.into()))
};
if num <= 0f64 {
return Err(PissError::NumberNotPositive)
}
let multiplier = parse_suffix(suffix_text)?;
Ok(PissAmount {
to_piss: (num * multiplier as f64) as u128
})
}
impl FromStr for PissAmount {
type Err = PissError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
parse_file_size(s)
}
}