From 2dad06cae3991d7de819f39cf7d63f8e2b519aca Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Thu, 8 Jun 2023 00:55:42 -0400 Subject: [PATCH] initial --- .gitignore | 1 + Cargo.lock | 16 ++++++++++++ Cargo.toml | 9 +++++++ src/error.rs | 17 +++++++++++++ src/lib.rs | 58 ++++++++++++++++++++++++++++++++++++++++++ src/parse.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 172 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/error.rs create mode 100644 src/lib.rs create mode 100644 src/parse.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6ce4a59 --- /dev/null +++ b/Cargo.lock @@ -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", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f2be850 --- /dev/null +++ b/Cargo.toml @@ -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" diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..399eb33 --- /dev/null +++ b/src/error.rs @@ -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") + } + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..ebf3274 --- /dev/null +++ b/src/lib.rs @@ -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::::with_capacity(amount).leak(); +} + +thread_local!(static TOLIET: RefCell>> = RefCell::new(Vec::new())); + +fn leak_lazy(amount: usize) { + TOLIET.with(|t| { + t.borrow_mut().push(Vec::::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>(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>(amount: T, method: Toliet) { + leak(amount, method); +} diff --git a/src/parse.rs b/src/parse.rs new file mode 100644 index 0000000..edfd9c5 --- /dev/null +++ b/src/parse.rs @@ -0,0 +1,71 @@ +use std::str::FromStr; +use crate::{error::PissError, PissAmount}; + +impl From for PissAmount +where T: Into { + fn from(num: T) -> PissAmount { + PissAmount { + to_piss: num.into() + } + } +} + +fn parse_suffix(s: &str) -> Result { + 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 { + 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::() 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 { + parse_file_size(s) + } +}