use crate::context::GlobalParams;
use crate::error::Result;
use crate::modules::{Module, ModuleResult, parse_params};
#[cfg(feature = "docs")]
use rash_derive::DocJsonSchema;
use minijinja::Value;
#[cfg(feature = "docs")]
use schemars::{JsonSchema, Schema};
use serde::Deserialize;
use serde_norway::Value as YamlValue;
use std::time::Duration;
const DEFAULT_SECONDS: u64 = 0;
const DEFAULT_MINUTES: u64 = 0;
fn default_seconds() -> u64 {
DEFAULT_SECONDS
}
fn default_minutes() -> u64 {
DEFAULT_MINUTES
}
#[derive(Debug, PartialEq, Deserialize)]
#[cfg_attr(feature = "docs", derive(JsonSchema, DocJsonSchema))]
#[serde(deny_unknown_fields)]
pub struct Params {
#[serde(default = "default_seconds")]
seconds: u64,
#[serde(default = "default_minutes")]
minutes: u64,
#[serde(default)]
prompt: Option<String>,
}
fn pause(params: Params, check_mode: bool) -> Result<ModuleResult> {
let total_seconds = params.minutes * 60 + params.seconds;
if total_seconds == 0 {
return Ok(ModuleResult::new(false, None, Some("0".to_string())));
}
if !check_mode {
if let Some(ref prompt) = params.prompt {
eprintln!("{}", prompt);
}
std::thread::sleep(Duration::from_secs(total_seconds));
}
Ok(ModuleResult::new(
!check_mode,
None,
Some(total_seconds.to_string()),
))
}
#[derive(Debug)]
pub struct Pause;
impl Module for Pause {
fn get_name(&self) -> &str {
"pause"
}
fn exec(
&self,
_: &GlobalParams,
optional_params: YamlValue,
_vars: &Value,
check_mode: bool,
) -> Result<(ModuleResult, Option<Value>)> {
Ok((pause(parse_params(optional_params)?, check_mode)?, None))
}
#[cfg(feature = "docs")]
fn get_json_schema(&self) -> Option<Schema> {
Some(Params::get_json_schema())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::error::ErrorKind;
#[test]
fn test_parse_params_seconds() {
let yaml: YamlValue = serde_norway::from_str(
r#"
seconds: 5
"#,
)
.unwrap();
let params: Params = parse_params(yaml).unwrap();
assert_eq!(
params,
Params {
seconds: 5,
minutes: 0,
prompt: None,
}
);
}
#[test]
fn test_parse_params_minutes() {
let yaml: YamlValue = serde_norway::from_str(
r#"
minutes: 2
"#,
)
.unwrap();
let params: Params = parse_params(yaml).unwrap();
assert_eq!(
params,
Params {
seconds: 0,
minutes: 2,
prompt: None,
}
);
}
#[test]
fn test_parse_params_both() {
let yaml: YamlValue = serde_norway::from_str(
r#"
seconds: 30
minutes: 1
prompt: "Waiting..."
"#,
)
.unwrap();
let params: Params = parse_params(yaml).unwrap();
assert_eq!(
params,
Params {
seconds: 30,
minutes: 1,
prompt: Some("Waiting...".to_string()),
}
);
}
#[test]
fn test_parse_params_default() {
let yaml: YamlValue = serde_norway::from_str("{}").unwrap();
let params: Params = parse_params(yaml).unwrap();
assert_eq!(
params,
Params {
seconds: 0,
minutes: 0,
prompt: None,
}
);
}
#[test]
fn test_pause_zero() {
let params = Params {
seconds: 0,
minutes: 0,
prompt: None,
};
let result = pause(params, false).unwrap();
assert!(!result.get_changed());
}
#[test]
fn test_pause_check_mode() {
let params = Params {
seconds: 5,
minutes: 0,
prompt: None,
};
let result = pause(params, true).unwrap();
assert!(!result.get_changed());
}
#[test]
fn test_pause_random_field() {
let yaml: YamlValue = serde_norway::from_str(
r#"
seconds: 5
invalid: field
"#,
)
.unwrap();
let error = parse_params::<Params>(yaml).unwrap_err();
assert_eq!(error.kind(), ErrorKind::InvalidData);
}
}