use std::sync::atomic::{AtomicBool, Ordering};
use anyhow::Result;
use crate::error::{CodedError, ErrorCode};
static IN_SESSION: AtomicBool = AtomicBool::new(false);
pub fn claim_stdin() {
IN_SESSION.store(true, Ordering::Relaxed);
}
pub fn check_stdin<C: ErrorCode>(code: C) -> Result<()> {
if in_session() {
let message = "Cannot read input from stdin inside a session, \
pass it as an argument or a file path";
return Err(CodedError::new(code, message).into());
}
Ok(())
}
pub fn in_session() -> bool {
IN_SESSION.load(Ordering::Relaxed)
}
#[cfg(test)]
mod tests {
use schemars::JsonSchema;
use serde::Serialize;
use crate::{
error::code_of,
session::{check_stdin, claim_stdin, in_session},
};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, JsonSchema)]
#[serde(rename_all = "kebab-case")]
enum TestCode {
StdinTaken,
}
#[test]
fn a_claimed_stdin_refuses_command_input_with_the_code() {
claim_stdin();
assert!(in_session());
let err = check_stdin(TestCode::StdinTaken).unwrap_err();
assert_eq!(code_of(&err), Some(TestCode::StdinTaken));
assert!(err.to_string().starts_with("Cannot read input from stdin"));
}
}