117 lines
2.8 KiB
Rust
117 lines
2.8 KiB
Rust
mod args;
|
|
mod charset;
|
|
mod color;
|
|
mod sneakers;
|
|
|
|
use libc::{c_char, c_int, c_void};
|
|
use std::ffi::CString;
|
|
use std::process;
|
|
|
|
use color::Color;
|
|
|
|
const VERSION: &str = "2.0.0";
|
|
|
|
extern "C" {
|
|
fn nmstermio_set_clearscr(_: c_int);
|
|
fn nmseffect_exec(
|
|
input: *const c_char,
|
|
len: c_int,
|
|
autodecrypt_c: c_int,
|
|
maskblank_c: c_int,
|
|
clear_scr: c_int,
|
|
) -> c_char;
|
|
static mut foregroundColor: c_int;
|
|
}
|
|
|
|
///Sleep for the number of milliseconds indicated by argument
|
|
#[no_mangle]
|
|
pub extern "C" fn nmseffect_sleep(t: c_int) {
|
|
use std::time::Duration;
|
|
|
|
let dur = Duration::from_millis(t as u64);
|
|
std::thread::sleep(dur);
|
|
}
|
|
|
|
/// Return a random character from charTable[].
|
|
#[no_mangle]
|
|
pub extern "C" fn nmscharset_get_random() -> *const c_char {
|
|
let table = charset::CHAR_TABLE;
|
|
let idx: u16 = rand::random::<u16>();
|
|
|
|
let bytes = table[(idx as usize) % table.len()];
|
|
bytes.as_ptr() as *const c_char
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub extern "C" fn rust_main() {
|
|
println!("Hello from rust");
|
|
|
|
let args = match args::parse_arguments() {
|
|
Ok(args) => args,
|
|
Err(e) => {
|
|
println!("{e}");
|
|
process::exit(1);
|
|
}
|
|
};
|
|
println!("{:?}", args);
|
|
|
|
if args.version {
|
|
println!("nms version {VERSION}");
|
|
process::exit(0);
|
|
}
|
|
|
|
if let Some(color) = args.foreground {
|
|
let color = Color::try_from(color).unwrap_or_default();
|
|
let n = color as c_int;
|
|
unsafe {
|
|
foregroundColor = n;
|
|
}
|
|
}
|
|
|
|
if args.clear_screen {
|
|
unsafe {
|
|
nmstermio_set_clearscr(2);
|
|
}
|
|
}
|
|
|
|
|
|
let input = get_input("Enter input: ");
|
|
if input.len() == 0 {
|
|
eprintln!("Input is empty"); //TODO use error_log()/error_print() abstraction
|
|
process::exit(1);
|
|
}
|
|
|
|
exec_effect(input, args.autodecrypt, args.mask_blanks, args.clear_screen);
|
|
}
|
|
|
|
fn exec_effect(input: String, autodecrypt: bool, maskblank: bool, clear_screen: bool) {
|
|
|
|
let maskblank_c = if maskblank { 1 } else { 0 };
|
|
let autodecrypt_c = if autodecrypt { 1 } else { 0};
|
|
|
|
let output_cstring = CString::new(input).unwrap();
|
|
let ptr = output_cstring.as_ptr();
|
|
let len = output_cstring.as_bytes().len();
|
|
let clear = if clear_screen { 1 } else { 0 };
|
|
let _r = unsafe { nmseffect_exec(ptr, len as i32, autodecrypt_c, maskblank_c, clear) };
|
|
|
|
}
|
|
|
|
fn get_input(prompt: &str) -> String {
|
|
use std::io::{Read, Write};
|
|
|
|
let mut stdin = std::io::stdin();
|
|
let mut stdout = std::io::stdout();
|
|
let mut buf = String::new();
|
|
|
|
if atty::is(atty::Stream::Stdin) {
|
|
print!("{prompt}");
|
|
stdout.flush().unwrap();
|
|
stdin.read_line(&mut buf).unwrap();
|
|
} else {
|
|
stdin.read_to_string(&mut buf).unwrap();
|
|
}
|
|
|
|
buf
|
|
}
|