use std::fmt;
use std::str::FromStr;
pub const PRIMER_FULL: &str = include_str!("../docs/primer.md");
pub const PRIMER_BRIEF: &str = include_str!("../docs/primer_brief.md");
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PrimerSection {
Format,
Examples,
Tips,
Full,
}
impl fmt::Display for PrimerSection {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PrimerSection::Format => write!(f, "format"),
PrimerSection::Examples => write!(f, "examples"),
PrimerSection::Tips => write!(f, "tips"),
PrimerSection::Full => write!(f, "full"),
}
}
}
impl FromStr for PrimerSection {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"format" => Ok(PrimerSection::Format),
"examples" => Ok(PrimerSection::Examples),
"tips" => Ok(PrimerSection::Tips),
"full" => Ok(PrimerSection::Full),
_ => Err(format!("Unknown section '{}'. Available: format, examples, tips, full", s)),
}
}
}
pub fn get_primer(section: PrimerSection, brief: bool) -> &'static str {
if brief {
return PRIMER_BRIEF;
}
match section {
PrimerSection::Full => PRIMER_FULL,
PrimerSection::Format => extract_section(PRIMER_FULL, "Format Quick Reference"),
PrimerSection::Examples => extract_section(PRIMER_FULL, "Complete Example"),
PrimerSection::Tips => extract_section(PRIMER_FULL, "Best Practices"),
}
}
fn extract_section(content: &'static str, heading: &str) -> &'static str {
let search = format!("## {}", heading);
if let Some(start_idx) = content.find(&search) {
let section_content = &content[start_idx..];
let after_heading = §ion_content[3..]; if let Some(next_section) = after_heading.find("\n## ") {
&content[start_idx..start_idx + 3 + next_section]
} else {
section_content
}
} else {
content
}
}
pub fn list_sections() -> &'static [&'static str] {
&["format", "examples", "tips", "full"]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_primer_section_from_str() {
assert_eq!(PrimerSection::from_str("format").unwrap(), PrimerSection::Format);
assert_eq!(PrimerSection::from_str("FORMAT").unwrap(), PrimerSection::Format);
assert_eq!(PrimerSection::from_str("examples").unwrap(), PrimerSection::Examples);
assert_eq!(PrimerSection::from_str("tips").unwrap(), PrimerSection::Tips);
assert_eq!(PrimerSection::from_str("full").unwrap(), PrimerSection::Full);
assert!(PrimerSection::from_str("invalid").is_err());
}
#[test]
fn test_primer_section_display() {
assert_eq!(format!("{}", PrimerSection::Format), "format");
assert_eq!(format!("{}", PrimerSection::Examples), "examples");
assert_eq!(format!("{}", PrimerSection::Tips), "tips");
assert_eq!(format!("{}", PrimerSection::Full), "full");
}
#[test]
fn test_get_primer_full() {
let content = get_primer(PrimerSection::Full, false);
assert!(content.contains("# Pixelsrc Primer"));
assert!(content.contains("## Format Quick Reference"));
}
#[test]
fn test_get_primer_brief() {
let content = get_primer(PrimerSection::Full, true);
assert!(content.contains("# Pixelsrc Quick Reference"));
assert!(content.len() < 3500);
}
#[test]
fn test_get_primer_format_section() {
let content = get_primer(PrimerSection::Format, false);
assert!(content.contains("## Format Quick Reference"));
assert!(content.contains("Object Types"));
}
#[test]
fn test_get_primer_examples_section() {
let content = get_primer(PrimerSection::Examples, false);
assert!(content.contains("## Complete Example"));
assert!(content.contains("coin"));
}
#[test]
fn test_get_primer_tips_section() {
let content = get_primer(PrimerSection::Tips, false);
assert!(content.contains("## Best Practices"));
assert!(content.contains("DO"));
}
}