pray-core 1.10.0

Core library for Prayfile, the package manager for the language placed before inference
Documentation
use super::call::parse_call;
use crate::literal::LiteralValue;
use crate::manifest::{DestinationMode, RenderPolicy};
use crate::{PrayError, PrayResult};
use std::collections::BTreeMap;

pub(super) fn parse_render_policy(rest: &str) -> PrayResult<RenderPolicy> {
    let (_, keywords) = parse_call(rest)?;
    for key in keywords.keys() {
        if !matches!(key.as_str(), "mode" | "conflict" | "churn" | "header") {
            return Err(PrayError::Parse {
                kind: "manifest",
                message: format!("render does not accept {key}"),
            });
        }
    }
    Ok(RenderPolicy {
        mode: keywords
            .get("mode")
            .and_then(|value| value.as_string())
            .unwrap_or("managed")
            .to_string(),
        conflict: keywords
            .get("conflict")
            .and_then(|value| value.as_string())
            .unwrap_or("fail")
            .to_string(),
        churn: keywords
            .get("churn")
            .and_then(|value| value.as_string())
            .unwrap_or("minimal")
            .to_string(),
        header: keywords
            .get("header")
            .and_then(|value| value.as_bool())
            .unwrap_or(true),
    })
}

pub(super) fn destination_header_keyword(
    mode: DestinationMode,
    keywords: &BTreeMap<String, LiteralValue>,
) -> PrayResult<Option<bool>> {
    let label = match mode {
        DestinationMode::Compose => "compose",
        DestinationMode::Tree => "tree",
        DestinationMode::Legacy => "destination",
    };
    for key in keywords.keys() {
        if key != "header" {
            return Err(PrayError::Parse {
                kind: "manifest",
                message: format!("{label} does not accept {key}"),
            });
        }
    }
    let Some(value) = keywords.get("header") else {
        return Ok(None);
    };
    if mode != DestinationMode::Compose {
        return Err(PrayError::Parse {
            kind: "manifest",
            message: format!("{label} does not accept header"),
        });
    }
    value.as_bool().map(Some).ok_or_else(|| PrayError::Parse {
        kind: "manifest",
        message: "header must be true or false".to_string(),
    })
}