mirror of
https://github.com/ivabus/smurf
synced 2024-11-22 00:15:10 +03:00
0.2
This commit is contained in:
parent
b616ffce1d
commit
f96e9b8be6
6 changed files with 128 additions and 25 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "smurf"
|
name = "smurf"
|
||||||
version = "0.1.1"
|
version = "0.2.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = ["Ivan Bushchik <ivabus@ivabus.dev>"]
|
authors = ["Ivan Bushchik <ivabus@ivabus.dev>"]
|
||||||
description = "SMall Useful Rust Functions"
|
description = "SMall Useful Rust Functions"
|
||||||
|
|
47
README.md
47
README.md
|
@ -2,12 +2,51 @@
|
||||||
|
|
||||||
> SMall Useful Rust Functions
|
> SMall Useful Rust Functions
|
||||||
|
|
||||||
## Components
|
## Components
|
||||||
|
|
||||||
|
### IO
|
||||||
|
|
||||||
|
- macros input!(T) and input_vec!(T), that could be used to simplify stdin process
|
||||||
|
- read_file_to_str() basically reads file to string (yes.)
|
||||||
|
|
||||||
### Shell
|
### Shell
|
||||||
|
|
||||||
- macro `shell!`
|
- macros shell!()
|
||||||
|
## Usage
|
||||||
|
|
||||||
### File
|
Add this to your `Cargo.toml`:
|
||||||
|
|
||||||
- function `read_to_str`
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
smurf = "0.2"
|
||||||
|
```
|
||||||
|
|
||||||
|
and this to your crate root:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
extern crate smurf;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use smurf;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
print!("What is your name? ");
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
let user_name = input!(String);
|
||||||
|
print!("What is your age? ");
|
||||||
|
std::io::stdout().flush().unwrap();
|
||||||
|
let user_age = input!(u8);
|
||||||
|
let shell_output = shell!("echo Hello {} of age {}", user_name, user_age); // Returns ShellResult {code: i32, stdout: String, stderr: String}
|
||||||
|
println!("Shell output: {}", shell_output.stdout);
|
||||||
|
println!("Shell stderr: {}", shell_output.stderr);
|
||||||
|
println!("Shell exit code: {}", shell_output.code);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE-MIT)
|
||||||
|
|
17
src/file.rs
17
src/file.rs
|
@ -1,17 +0,0 @@
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{prelude::*, BufReader};
|
|
||||||
|
|
||||||
pub fn read_to_str(path: &std::path::PathBuf) -> String {
|
|
||||||
let file = File::open(&path);
|
|
||||||
let file = match file {
|
|
||||||
Ok(data) => data,
|
|
||||||
Err(_) => {
|
|
||||||
eprintln!("Cannot open file \"{}\"", path.display());
|
|
||||||
std::process::exit(2)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut buf_reader = BufReader::new(file);
|
|
||||||
let mut content = String::new();
|
|
||||||
buf_reader.read_to_string(&mut content).unwrap();
|
|
||||||
content
|
|
||||||
}
|
|
40
src/io.rs
Normal file
40
src/io.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{prelude::*, BufReader};
|
||||||
|
|
||||||
|
pub fn read_file_to_str(path: &std::path::PathBuf) -> Option<String> {
|
||||||
|
let file = File::open(&path);
|
||||||
|
let file = match file {
|
||||||
|
Ok(data) => data,
|
||||||
|
Err(_) => {
|
||||||
|
eprintln!("Cannot open file \"{}\"", path.display());
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut buf_reader = BufReader::new(file);
|
||||||
|
let mut content = String::new();
|
||||||
|
buf_reader.read_to_string(&mut content).unwrap();
|
||||||
|
Some(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! input {
|
||||||
|
($t:ty) => {
|
||||||
|
{
|
||||||
|
let mut input = String::new();
|
||||||
|
std::io::stdin().read_line(&mut input).unwrap();
|
||||||
|
input.trim().parse::<$t>().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! input_vec {
|
||||||
|
($t:ty) => {
|
||||||
|
{
|
||||||
|
let mut input = String::new();
|
||||||
|
std::io::stdin().read_line(&mut input).unwrap();
|
||||||
|
input.trim().split_whitespace().map(|x| x.parse::<$t>().unwrap()).collect::<Vec<$t>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod file;
|
pub mod io;
|
||||||
pub mod shell;
|
pub mod shell;
|
||||||
|
|
45
src/shell.rs
45
src/shell.rs
|
@ -12,8 +12,7 @@ pub struct ShellResult {
|
||||||
pub stdout: String,
|
pub stdout: String,
|
||||||
pub stderr: String,
|
pub stderr: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn run(command: String) -> ShellResult {
|
pub fn run(command: String) -> ShellResult {
|
||||||
let mut iter = command.split_whitespace();
|
let mut iter = command.split_whitespace();
|
||||||
let mut current = iter.next();
|
let mut current = iter.next();
|
||||||
|
@ -24,6 +23,7 @@ pub fn run(command: String) -> ShellResult {
|
||||||
}
|
}
|
||||||
let command = Command::new(&words[0])
|
let command = Command::new(&words[0])
|
||||||
.args(&words[1..])
|
.args(&words[1..])
|
||||||
|
.env("PATH", "/bin:/usr/bin") // TODO: Make this configurable
|
||||||
.output()
|
.output()
|
||||||
.expect(&format!("Failed to execute '{}'", command));
|
.expect(&format!("Failed to execute '{}'", command));
|
||||||
return ShellResult {
|
return ShellResult {
|
||||||
|
@ -32,3 +32,44 @@ pub fn run(command: String) -> ShellResult {
|
||||||
stderr: String::from_utf8(command.stderr).unwrap(),
|
stderr: String::from_utf8(command.stderr).unwrap(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn test_shell_macro() {
|
||||||
|
let result = shell!("echo hello");
|
||||||
|
assert_eq!(result.code, 0);
|
||||||
|
assert_eq!(result.stdout, "hello\n");
|
||||||
|
assert_eq!(result.stderr, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* You literally can't use pipe using std::process::Command */
|
||||||
|
// TODO: figure out how to test this
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn test_shell_macro_with_stderr() {
|
||||||
|
let result = shell!("echo hello 1>&2");
|
||||||
|
assert_eq!(result.code, 0);
|
||||||
|
assert_eq!(result.stdout, "");
|
||||||
|
assert_eq!(result.stderr, "hello\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_shell_macro_with_args() {
|
||||||
|
let result = shell!("echo {} {}", "hello", "world");
|
||||||
|
assert_eq!(result.code, 0);
|
||||||
|
assert_eq!(result.stdout, "hello world\n");
|
||||||
|
assert_eq!(result.stderr, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: figure out how to test this
|
||||||
|
#[ignore]
|
||||||
|
#[test]
|
||||||
|
fn test_shell_macro_with_code() {
|
||||||
|
let result = shell!("sh -c exit 1");
|
||||||
|
assert_eq!(result.code, 1);
|
||||||
|
assert_eq!(result.stdout, "");
|
||||||
|
assert_eq!(result.stderr, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue