Skip to content

Commit

Permalink
Merge pull request #50 from kdesjard/stdout_stderr_to_vec
Browse files Browse the repository at this point in the history
  • Loading branch information
genedna authored Dec 11, 2023
2 parents a7ed957 + d2806af commit dd2d5dd
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 17 deletions.
39 changes: 30 additions & 9 deletions src/task/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::{Complex, EnvVar, Input, Output};
use std::process::Command;
use std::sync::Arc;

use crate::task::Content;

/// [`CommandAction`] is a specific implementation of [`Complex`], used to execute operating system commands.
pub struct CommandAction {
command: String,
Expand Down Expand Up @@ -33,19 +35,38 @@ impl Complex for CommandAction {
args.push(inp)
}
});
let out = match cmd.args(args).output() {
Ok(o) => o,
Err(e) => return Output::Err(e.to_string()),
let(code,out) = match cmd.args(args).output() {
Ok(o) => {
(0,o)
},
Err(e) => {
return Output::Err(
e.raw_os_error(),
Some(Content::new(e.to_string()))
)
}
};

if out.status.success() {
let mut out = String::from_utf8(out.stdout).unwrap();
let stdout: Vec<String> = {
let out = String::from_utf8(out.stdout).unwrap_or("".to_string());
if cfg!(target_os = "windows") {
out = out.replace("\r\n", " ").replace('\n', " ");
out.rsplit_terminator("\r\n").map(str::to_string).collect()
} else {
out.split_terminator('\n').map(str::to_string).collect()
}
Output::new(out)
};
let stderr: Vec<String> = {
let out = String::from_utf8(out.stderr).unwrap_or("".to_string());
if cfg!(target_os = "windows") {
out.rsplit_terminator("\r\n").map(str::to_string).collect()
} else {
out.split_terminator('\n').map(str::to_string).collect()
}
};
let output = Content::new((stdout,stderr));
if out.status.success() {
Output::new(output)
} else {
Output::Err(String::from_utf8(out.stderr).unwrap())
Output::Err(Some(code),Some(output))
}
}
}
3 changes: 2 additions & 1 deletion src/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ use std::sync::atomic::AtomicUsize;
pub use self::action::{Action, Complex, Simple};
pub use self::cmd::CommandAction;
pub use self::default_task::DefaultTask;
pub(crate) use self::state::{Content, ExecState};
pub use self::state::Content;
pub(crate) use self::state::ExecState;
pub use self::state::{Input, Output};

mod action;
Expand Down
21 changes: 14 additions & 7 deletions src/task/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
//!
//! ```rust
//! use dagrs::Output;
//! let err_out = Output::Err("some error messages!".to_string());
//! use dagrs::task::Content;
//! let err_out = Output::Err(None,Some(Content::new("some error messages!".to_string())));
//! ```
//!
//! # [`Input`]
Expand Down Expand Up @@ -95,7 +96,7 @@ pub(crate) struct ExecState {
#[derive(Debug)]
pub enum Output {
Out(Option<Content>),
Err(String),
Err(Option<i32>,Option<Content>),
}

/// Task's input value.
Expand Down Expand Up @@ -165,14 +166,14 @@ impl Output {
}

/// Construct an [`Output`]` with an error message.
pub fn error(msg: String) -> Self {
Self::Err(msg)
pub fn error(code: Option<i32>, msg: String) -> Self {
Self::Err(code,Some(Content::new(msg)))
}

/// Determine whether [`Output`] stores error information.
pub(crate) fn is_err(&self) -> bool {
match self {
Self::Err(_) => true,
Self::Err(_,_) => true,
Self::Out(_) => false,
}
}
Expand All @@ -181,15 +182,21 @@ impl Output {
pub(crate) fn get_out(&self) -> Option<Content> {
match self {
Self::Out(ref out) => out.clone(),
Self::Err(_) => None,
Self::Err(_,_) => None,
}
}

/// Get error information stored in [`Output`].
pub(crate) fn get_err(&self) -> Option<String> {
match self {
Self::Out(_) => None,
Self::Err(err) => Some(err.to_string()),
Self::Err(_,err) => {
if let Some(e) = err {
Some(e.get::<String>()?.to_string())
} else {
None
}
}
}
}
}
Expand Down

0 comments on commit dd2d5dd

Please sign in to comment.