initial
This commit is contained in:
commit
2dad06cae3
6 changed files with 172 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
16
Cargo.lock
generated
Normal file
16
Cargo.lock
generated
Normal 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
9
Cargo.toml
Normal 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
17
src/error.rs
Normal 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
58
src/lib.rs
Normal 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
71
src/parse.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue