conch_runtime_pshaw/eval/param_subst/
error.rs

1use super::is_present;
2use crate::env::StringWrapper;
3use crate::error::ExpansionError;
4use crate::eval::{Fields, ParamEval, TildeExpansion, WordEval, WordEvalConfig};
5use std::fmt::Display;
6
7/// Evaluates a parameter or raises an error if it is empty.
8///
9/// First, `param` will be evaluated and returned as is as long as the result is
10/// non-empty, or if the result is defined-but-empty and `strict = false`.
11///
12/// Otherwise, `error` will be evaluated using `cfg`, and the result will populate
13/// an `ExpansionError::EmptyParameter`.
14///
15/// Note: field splitting will neither be done on the parameter, nor the error message.
16pub async fn error<P, W, E>(
17    strict: bool,
18    param: &P,
19    error: Option<W>,
20    env: &mut E,
21    cfg: TildeExpansion,
22) -> Result<Fields<W::EvalResult>, W::Error>
23where
24    P: ?Sized + ParamEval<E, EvalResult = W::EvalResult> + Display,
25    W: WordEval<E>,
26    W::Error: From<ExpansionError>,
27    E: ?Sized,
28{
29    if let Some(fields) = is_present(strict, param.eval(false, env)) {
30        return Ok(fields);
31    }
32
33    let msg = match error {
34        Some(w) => {
35            let future = w.eval_with_config(
36                env,
37                WordEvalConfig {
38                    split_fields_further: false,
39                    tilde_expansion: cfg,
40                },
41            );
42
43            future.await?.await.join().into_owned()
44        }
45        None => String::from("parameter null or not set"),
46    };
47
48    let param_display = param.to_string();
49    Err(ExpansionError::EmptyParameter(param_display, msg).into())
50}