knave 0.12.6

A Lisp programming language for humans and agents that infers types and ownership and compiles to readable Rust
Documentation
use std::path::PathBuf;

use super::exit_status::ExitStatus;
use super::project_task::{ProjectTask, TaskName};
use super::task_catalog::TaskCatalog;
use super::terminal::Terminal;
use crate::build::BuildProfile;
use crate::reader::StringLiteral;

pub struct TaskRunners<'c> {
    catalog: &'c TaskCatalog,
}

impl<'c> TaskRunners<'c> {
    pub fn new(catalog: &'c TaskCatalog) -> Self {
        Self { catalog }
    }

    pub fn build(
        &self,
        terminal: &mut Terminal,
        task: &ProjectTask<'_>,
        profile: BuildProfile,
    ) -> Result<PathBuf, ExitStatus> {
        let signatures = self
            .catalog
            .signatures(terminal, std::slice::from_ref(task.name()))?;
        let runner = Self::runner(task.name(), &signatures[0]);
        let entered = self.catalog.entered_program(terminal, &runner)?;
        let checked = terminal.check_expanded(&entered.program)?;
        let emitted = terminal.emit_checked(&checked)?;
        terminal.build_task(&emitted, task, profile)
    }

    pub fn check(&self, terminal: &mut Terminal) -> Result<(), ExitStatus> {
        let names = self.catalog.names(terminal)?;
        let signatures = self.catalog.signatures(terminal, &names)?;
        let runners: Vec<String> = names
            .iter()
            .zip(&signatures)
            .map(|(name, signature)| Self::runner(name, signature))
            .collect();
        let (block, _) = TaskCatalog::block_of(&runners);
        let entered = self.catalog.entered_program(terminal, &block)?;
        terminal.check_expanded(&entered.program).map(|_| ())
    }

    fn runner(name: &TaskName, signature: &str) -> String {
        format!(
            "(run-task {} {})",
            StringLiteral::quoted(name.as_str()),
            StringLiteral::quoted(signature)
        )
    }
}