commit 3c05f5f26ba01ca73b6ed43aa8d95f49cc6f5470 Author: Avril Date: Thu Apr 30 21:10:42 2020 +0100 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80aca69 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +Cargo.lock +*~ diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..601b3fb --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rng" +version = "0.1.0" +authors = ["Avril "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +getrandom = "0.1" \ No newline at end of file diff --git a/src/impl.rs b/src/impl.rs new file mode 100644 index 0000000..38259ec --- /dev/null +++ b/src/impl.rs @@ -0,0 +1,51 @@ +use super::*; +use getrandom::*; + +pub fn range(start: f64, end: f64, mut repeat: usize) -> Result<(), Error> +{ + if repeat < 1 { + repeat = 1; + } + for _ in 0..repeat { + let value = double()?; + println!("{}", start + (value * (end-start))); + } + + Ok(()) +} +pub fn round(start: f64, end: f64, mut repeat: usize) -> Result<(), Error> +{ + if repeat < 1 { + repeat = 1; + } + for _ in 0..repeat { + let value = double()?; + println!("{}", ((start + (value * (end-start)))).round() as i64); + } + + Ok(()) +} +pub fn ceil(start: f64, end: f64, mut repeat: usize) -> Result<(), Error> +{ + if repeat < 1 { + repeat = 1; + } + for _ in 0..repeat { + let value = double()?; + println!("{}", (start + (value * (end-start))).ceil() as i64); + } + + Ok(()) +} +pub fn floor(start: f64, end: f64, mut repeat: usize) -> Result<(), Error> +{ + if repeat < 1 { + repeat = 1; + } + for _ in 0..repeat { + let value = double()?; + println!("{}", (start + (value * (end-start))).floor() as i64); + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ad80b07 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,171 @@ +#![allow(dead_code)] + +extern crate getrandom; + +use getrandom::*; + +mod r#impl; + +fn get() -> Result +{ + let mut value: T = Default::default(); + unsafe { + let mut slice = std::slice::from_raw_parts_mut(&mut value as *mut T as *mut u8, std::mem::size_of::()); + populate(&mut slice)?; + } + + Ok(value) +} + +fn double() -> Result +{ + let long: i64 = get::()?; + + Ok( ((long & ((1i64 << 53) - 1)) as f64) * (1_f64 / ((1_i64 << 53) as f64))) +} + +fn populate(mut value: &mut [u8]) -> Result<(), Error> +{ + getrandom(&mut value)?; + + Ok(()) +} + +fn int(low: i32, high: i32) -> Result +{ + let value = double()?; + return Ok(low + (value * (high - low) as f64).floor() as i32); +} + +fn usage() +{ + println!("Usage: rng --range []"); + println!("Usage: rng --floor []"); + println!("Usage: rng --round []"); + println!("Usage: rng --ceil []"); + println!("Usage: rng --of "); + println!("Usage: rng --shuffle "); +} + +fn range(args: &[String]) -> Result<(), Error> +{ + if args.len() < 2 { + usage(); + } else { + let start: f64 = args[0].parse().expect("Not a number (start)."); + let end: f64 = args[1].parse().expect("Not a number (end)."); + if args.len() >= 3 { + let repeat: usize = args[2].parse().expect("Not a valid number (repeat)."); + + r#impl::range(start,end,repeat)?; + } else { + r#impl::range(start,end,1)?; + } + } + Ok(()) +} + +fn round(args: &[String]) -> Result<(), Error> +{ + if args.len() < 2 { + usage(); + } else { + let start: f64 = args[0].parse().expect("Not a number (start)."); + let end: f64 = args[1].parse().expect("Not a number (end)."); + if args.len() >= 3 { + let repeat: usize = args[2].parse().expect("Not a valid number (repeat)."); + + r#impl::round(start,end,repeat)?; + } else { + r#impl::round(start,end,1)?; + } + } + Ok(()) +} + +fn ceil(args: &[String]) -> Result<(), Error> +{ + if args.len() < 2 { + usage(); + } else { + let start: f64 = args[0].parse().expect("Not a number (start)."); + let end: f64 = args[1].parse().expect("Not a number (end)."); + if args.len() >= 3 { + let repeat: usize = args[2].parse().expect("Not a valid number (repeat)."); + + r#impl::ceil(start,end,repeat)?; + } else { + r#impl::ceil(start,end,1)?; + } + } + Ok(()) +} + +fn floor(args: &[String]) -> Result<(), Error> +{ + if args.len() < 2 { + usage(); + } else { + let start: f64 = args[0].parse().expect("Not a number (start)."); + let end: f64 = args[1].parse().expect("Not a number (end)."); + if args.len() >= 3 { + let repeat: usize = args[2].parse().expect("Not a valid number (repeat)."); + + r#impl::floor(start,end,repeat)?; + } else { + r#impl::floor(start,end,1)?; + } + } + Ok(()) +} + +fn of(args: &[String]) -> Result<(), Error> +{ + let max = args.len(); + let int = int(0, max as i32)? as usize; + + println!("{}", args[int]); + + Ok(()) +} + +fn shuffle(args: &[String]) -> Result<(), Error> +{ + let mut values: Vec = args.to_vec(); + + for i in (1..args.len()).rev() { + let j = int(0, i as i32)? as usize; + + values.swap(i, j); + } + + for a in values.iter() { + println!("{}", a); + } + + Ok(()) +} + +fn main() -> Result<(), Error> { + + let args: Vec = std::env::args().collect(); + + if args.len() < 2 { + usage(); + Ok(()) + } else { + match args[1].to_lowercase().as_str() { + "--range" => range(&args[2..])?, + "--round" => round(&args[2..])?, + "--ceil" => ceil(&args[2..])?, + "--floor" => floor(&args[2..])?, + "--of" => of(&args[2..])?, + "--shuffle" => shuffle(&args[2..])?, + _ => usage() + }; + Ok(()) + } +} + + +