thesa 4.6.0

Archive repositories, models, datasets, websites, assets, audio, scholarly papers, and technical reports
use crate::error::{Result, ThesaError};

const THESA_GUIDE: &str = include_str!("../AGENT_GUIDE.md");
const VALID_SELECTORS: &str = "all, thesa, repoforge/repos/repositories, modelforge/models, baseforge/datasets, siteforge/sites, assetforge/assets/3d, soundforge/audio/sounds, paperforge/papers/paper";

struct Guide {
    body: &'static str,
}

const GUIDES: [Guide; 8] = [
    Guide { body: THESA_GUIDE },
    Guide {
        body: repoforge::AGENT_GUIDE,
    },
    Guide {
        body: modelforge::AGENT_GUIDE,
    },
    Guide {
        body: baseforge::AGENT_GUIDE,
    },
    Guide {
        body: siteforge::AGENT_GUIDE,
    },
    Guide {
        body: assetforge::AGENT_GUIDE,
    },
    Guide {
        body: soundforge::AGENT_GUIDE,
    },
    Guide {
        body: paperforge::AGENT_GUIDE,
    },
];

pub(crate) fn render_agent_guides(selector: &str) -> Result<String> {
    let normalized = selector.trim().to_ascii_lowercase();
    let selected = match normalized.as_str() {
        "all" => GUIDES.iter().collect::<Vec<_>>(),
        "thesa" => vec![&GUIDES[0]],
        "repoforge" | "repos" | "repositories" => vec![&GUIDES[1]],
        "modelforge" | "models" => vec![&GUIDES[2]],
        "baseforge" | "datasets" => vec![&GUIDES[3]],
        "siteforge" | "sites" => vec![&GUIDES[4]],
        "assetforge" | "assets" | "3d" => vec![&GUIDES[5]],
        "soundforge" | "audio" | "sounds" => vec![&GUIDES[6]],
        "paperforge" | "papers" | "paper" => vec![&GUIDES[7]],
        _ => {
            return Err(ThesaError::Message(format!(
                "unknown agent selector '{selector}'; valid selectors: {VALID_SELECTORS}"
            )));
        }
    };

    let mut output = String::new();
    for (index, guide) in selected.into_iter().enumerate() {
        if index > 0 {
            output.push_str("\n---\n\n");
        }
        output.push_str(guide.body);
    }
    Ok(output)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn aliases_render_the_exact_selected_guide() {
        for (aliases, body) in [
            (
                &["repoforge", "repos", "repositories"][..],
                repoforge::AGENT_GUIDE,
            ),
            (&["modelforge", "models"][..], modelforge::AGENT_GUIDE),
            (&["baseforge", "datasets"][..], baseforge::AGENT_GUIDE),
            (&["siteforge", "sites"][..], siteforge::AGENT_GUIDE),
            (&["assetforge", "assets", "3d"][..], assetforge::AGENT_GUIDE),
            (
                &["soundforge", "audio", "sounds"][..],
                soundforge::AGENT_GUIDE,
            ),
            (
                &["paperforge", "papers", "paper"][..],
                paperforge::AGENT_GUIDE,
            ),
        ] {
            for alias in aliases {
                let output = render_agent_guides(alias).unwrap();
                assert_eq!(output, body);
            }
        }
        assert_eq!(render_agent_guides("thesa").unwrap(), THESA_GUIDE);
    }

    #[test]
    fn all_contains_every_section_and_unknown_lists_valid_selectors() {
        let output = render_agent_guides("all").unwrap();
        for guide in GUIDES {
            assert!(output.contains(guide.body));
        }
        assert_eq!(output.matches("\n---\n").count(), GUIDES.len() - 1);
        let error = render_agent_guides("unknown").unwrap_err().to_string();
        assert!(error.contains("valid selectors:"));
        assert!(error.contains("paperforge/papers/paper"));
    }
}