-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
124 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
use std::io::{Read, Result, Write}; | ||
|
||
pub fn process_input<R: Read, W: Write>( | ||
input: &mut R, | ||
output: &mut W, | ||
prefix: &str, | ||
suffix: &str, | ||
) -> Result<()> { | ||
let mut first_chunk = true; | ||
let mut buffer = [0; 1024]; | ||
|
||
loop { | ||
match input.read(&mut buffer) { | ||
Ok(0) => break, // end of input | ||
Ok(n) => { | ||
if first_chunk { | ||
output.write_all(prefix.as_bytes())?; | ||
first_chunk = false; | ||
} | ||
output.write_all(&buffer[..n])?; | ||
} | ||
Err(e) => return Err(e), | ||
} | ||
} | ||
|
||
if !first_chunk { | ||
// we actually got some input | ||
output.write_all(suffix.as_bytes())?; | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use super::*; | ||
use std::io::Cursor; | ||
|
||
macro_rules! test_process_input { | ||
($test_name:ident, $prefix:expr, $suffix:expr, $input:expr) => { | ||
#[test] | ||
fn $test_name() { | ||
let input = $input.as_bytes(); | ||
let mut output = std::io::Cursor::new(Vec::new()); | ||
|
||
let result = process_input(&mut Cursor::new(input), &mut output, $prefix, $suffix); | ||
assert!(result.is_ok()); | ||
|
||
let expected_output = if !input.is_empty() { | ||
format!("{}{}{}", $prefix, $input, $suffix) | ||
} else { | ||
"".into() | ||
}; | ||
|
||
let expected_output_as_bytes = expected_output.as_bytes(); | ||
let output_data: Vec<u8> = output.into_inner(); | ||
assert_eq!( | ||
expected_output_as_bytes, | ||
output_data, | ||
"\nexpected: {}\nGot: {}", | ||
String::from_utf8_lossy(expected_output_as_bytes), | ||
&expected_output | ||
); | ||
} | ||
}; | ||
} | ||
|
||
test_process_input!( | ||
test_with_prefix_and_suffix, | ||
"Prefix: ", | ||
" Suffix", | ||
"Input data" | ||
); | ||
test_process_input!( | ||
test_with_custom_prefix_suffix, | ||
"Start: ", | ||
" End", | ||
"Custom input" | ||
); | ||
test_process_input!(test_empty_input, "Pre: ", " Post", ""); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,14 @@ | ||
use std::io::{self, Read, Write}; | ||
use std::io; | ||
mod input_processing; | ||
|
||
fn main() { | ||
let mut output = io::stdout(); | ||
let mut input = io::stdin(); | ||
let mut buffer = [0; 1024]; // You can adjust the buffer size as needed. | ||
let prefix = "Hello wolrd!\n```\n"; | ||
let suffix = "\n```"; | ||
|
||
let mut first_chunk = true; | ||
|
||
loop { | ||
match input.read(&mut buffer) { | ||
Ok(0) => break, // End of input | ||
Ok(n) => { | ||
if first_chunk { | ||
if let Err(e) = output.write_all(prefix.as_bytes()) { | ||
eprintln!("Error writing to stdout: {}", e); | ||
std::process::exit(1); | ||
} | ||
first_chunk = false; | ||
} | ||
if let Err(e) = output.write_all(&buffer[..n]) { | ||
eprintln!("Error writing to stdout: {}", e); | ||
std::process::exit(1); | ||
} | ||
} | ||
Err(e) => { | ||
eprintln!("Error reading from stdin: {}", e); | ||
std::process::exit(1); | ||
} | ||
} | ||
} | ||
|
||
if let Err(e) = output.write_all(suffix.as_bytes()) { | ||
eprintln!("Error writing to stdout: {}", e); | ||
if let Err(e) = | ||
input_processing::process_input(&mut input, &mut output, "Hello, World!\n```\n", "\n```\n") | ||
{ | ||
eprintln!("Error: {}", e); | ||
std::process::exit(1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
use std::io::{Read, Write}; | ||
use std::process::{Command, Stdio}; | ||
|
||
#[test] | ||
fn test_program_integration() { | ||
let hardcoded_prefix = "Hello, World!\n```\n"; | ||
let hardcoded_suffix = "\n```\n"; | ||
let input_data = "Input data"; | ||
|
||
// launch the program and get the streams | ||
let mut child = Command::new("cargo") | ||
.arg("run") | ||
.stdin(Stdio::piped()) | ||
.stdout(Stdio::piped()) | ||
.spawn() | ||
.expect("Failed to start the program"); | ||
let stdin = child.stdin.as_mut().expect("Failed to open stdin"); | ||
let stdout = child.stdout.as_mut().expect("Failed to open stdout"); | ||
|
||
// write | ||
stdin | ||
.write_all(input_data.as_bytes()) | ||
.expect("Failed to write to stdin"); | ||
drop(child.stdin.take()); | ||
|
||
// read | ||
let mut output_data = Vec::new(); | ||
stdout | ||
.read_to_end(&mut output_data) | ||
.expect("Failed to read from stdout"); | ||
|
||
// check | ||
let status = child.wait().expect("Failed to wait for child process"); | ||
assert!(status.success()); | ||
let expected_output = format!("{}{}{}", hardcoded_prefix, input_data, hardcoded_suffix); | ||
assert_eq!(String::from_utf8_lossy(&output_data), expected_output); | ||
} |