use crate::language::Language;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Topic {
DataTypes,
Concurrency,
ErrorHandling,
MemoryManagement,
InputOutput,
Testing,
Algorithms,
Patterns,
TypeSystems,
Performance,
Security,
KernelTopics,
QuantumComputing,
CompilerBootstrapping,
BinaryFormats,
LexingAndParsing,
IntermediateRepresentations,
CodeGeneration,
LinkingAndLoading,
OptimizationPasses,
SyscallsAndAbi,
VirtualMemory,
InterruptHandling,
ProcessAndScheduling,
Filesystems,
OwnershipAndBorrowing,
TraitAndTypeclassSystems,
MacroSystems,
ModuleSystems,
InstructionEncoding,
ElfAndExecutableFormats,
Allocators,
BootAndStartup,
}
impl std::fmt::Display for Topic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::DataTypes => f.write_str("Data Types"),
Self::Concurrency => f.write_str("Concurrency"),
Self::ErrorHandling => f.write_str("Error Handling"),
Self::MemoryManagement => f.write_str("Memory Management"),
Self::InputOutput => f.write_str("I/O"),
Self::Testing => f.write_str("Testing"),
Self::Algorithms => f.write_str("Algorithms"),
Self::Patterns => f.write_str("Design Patterns"),
Self::TypeSystems => f.write_str("Type Systems"),
Self::Performance => f.write_str("Performance"),
Self::Security => f.write_str("Security"),
Self::KernelTopics => f.write_str("Kernel Topics"),
Self::QuantumComputing => f.write_str("Quantum Computing"),
Self::CompilerBootstrapping => f.write_str("Compiler Bootstrapping"),
Self::BinaryFormats => f.write_str("Binary Formats"),
Self::LexingAndParsing => f.write_str("Lexing and Parsing"),
Self::IntermediateRepresentations => f.write_str("Intermediate Representations"),
Self::CodeGeneration => f.write_str("Code Generation"),
Self::LinkingAndLoading => f.write_str("Linking and Loading"),
Self::OptimizationPasses => f.write_str("Optimization Passes"),
Self::SyscallsAndAbi => f.write_str("Syscalls and ABI"),
Self::VirtualMemory => f.write_str("Virtual Memory"),
Self::InterruptHandling => f.write_str("Interrupt Handling"),
Self::ProcessAndScheduling => f.write_str("Process and Scheduling"),
Self::Filesystems => f.write_str("Filesystems"),
Self::OwnershipAndBorrowing => f.write_str("Ownership and Borrowing"),
Self::TraitAndTypeclassSystems => f.write_str("Trait and Typeclass Systems"),
Self::MacroSystems => f.write_str("Macro Systems"),
Self::ModuleSystems => f.write_str("Module Systems"),
Self::InstructionEncoding => f.write_str("Instruction Encoding"),
Self::ElfAndExecutableFormats => f.write_str("ELF and Executable Formats"),
Self::Allocators => f.write_str("Allocators"),
Self::BootAndStartup => f.write_str("Boot and Startup"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Concept {
pub id: String,
pub title: String,
pub topic: Topic,
pub description: String,
pub best_practices: Vec<BestPractice>,
pub gotchas: Vec<Gotcha>,
pub performance_notes: Vec<PerformanceNote>,
pub tags: Vec<String>,
pub examples: HashMap<Language, Example>,
}
impl Concept {
#[must_use]
pub fn example(&self, lang: Language) -> Option<&Example> {
self.examples.get(&lang)
}
#[must_use]
pub fn available_languages(&self) -> Vec<Language> {
let mut langs: Vec<Language> = self.examples.keys().copied().collect();
langs.sort_by_key(|l| l.display_name());
langs
}
#[must_use]
pub fn has_tag(&self, tag: &str) -> bool {
let lower = tag.to_lowercase();
self.tags.iter().any(|t| t.to_lowercase() == lower)
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BestPractice {
pub title: String,
pub explanation: String,
pub language: Option<Language>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Gotcha {
pub title: String,
pub explanation: String,
pub bad_example: Option<String>,
pub good_example: Option<String>,
pub language: Option<Language>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceNote {
pub title: String,
pub explanation: String,
pub evidence: Option<String>,
pub language: Option<Language>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Example {
pub language: Language,
pub code: String,
pub explanation: String,
pub source_path: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
fn sample_concept() -> Concept {
let mut examples = HashMap::new();
examples.insert(
Language::Rust,
Example {
language: Language::Rust,
code: "let s = format!(\"hello {}\", name);".into(),
explanation: "Rust uses the format! macro for string interpolation.".into(),
source_path: Some("strings/rust.rs".into()),
},
);
examples.insert(
Language::Python,
Example {
language: Language::Python,
code: "s = f\"hello {name}\"".into(),
explanation: "Python uses f-strings for interpolation.".into(),
source_path: Some("strings/python.py".into()),
},
);
Concept {
id: "string_interpolation".into(),
title: "String Interpolation".into(),
topic: Topic::DataTypes,
description: "Embedding expressions inside string literals.".into(),
best_practices: vec![BestPractice {
title: "Prefer interpolation over concatenation".into(),
explanation: "More readable and often more efficient.".into(),
language: None,
}],
gotchas: vec![Gotcha {
title: "Rust format! allocates a new String".into(),
explanation: "Use write! to avoid allocation when writing to a buffer.".into(),
bad_example: Some("let s = format!(\"x={}\", x);".into()),
good_example: Some("write!(buf, \"x={}\", x)?;".into()),
language: Some(Language::Rust),
}],
performance_notes: vec![PerformanceNote {
title: "write! over format! on hot paths".into(),
explanation: "format! allocates; write! appends to existing buffer.".into(),
evidence: Some("~40% fewer allocations in benchmarks".into()),
language: Some(Language::Rust),
}],
tags: vec![
"strings".into(),
"formatting".into(),
"interpolation".into(),
],
examples,
}
}
#[test]
fn concept_example_lookup() {
let c = sample_concept();
assert!(c.example(Language::Rust).is_some());
assert!(c.example(Language::Python).is_some());
assert!(c.example(Language::C).is_none());
}
#[test]
fn concept_available_languages() {
let c = sample_concept();
let langs = c.available_languages();
assert_eq!(langs.len(), 2);
}
#[test]
fn concept_has_tag() {
let c = sample_concept();
assert!(c.has_tag("strings"));
assert!(c.has_tag("STRINGS"));
assert!(!c.has_tag("concurrency"));
}
#[test]
fn concept_serde_roundtrip() {
let c = sample_concept();
let json = serde_json::to_string(&c).unwrap();
let decoded: Concept = serde_json::from_str(&json).unwrap();
assert_eq!(c.id, decoded.id);
assert_eq!(c.examples.len(), decoded.examples.len());
}
#[test]
fn topic_display() {
assert_eq!(Topic::DataTypes.to_string(), "Data Types");
assert_eq!(Topic::ErrorHandling.to_string(), "Error Handling");
}
#[test]
fn topic_display_compiler_topics() {
assert_eq!(Topic::LexingAndParsing.to_string(), "Lexing and Parsing");
assert_eq!(
Topic::IntermediateRepresentations.to_string(),
"Intermediate Representations"
);
assert_eq!(Topic::CodeGeneration.to_string(), "Code Generation");
assert_eq!(Topic::LinkingAndLoading.to_string(), "Linking and Loading");
assert_eq!(Topic::OptimizationPasses.to_string(), "Optimization Passes");
}
#[test]
fn topic_display_systems_topics() {
assert_eq!(Topic::SyscallsAndAbi.to_string(), "Syscalls and ABI");
assert_eq!(Topic::VirtualMemory.to_string(), "Virtual Memory");
assert_eq!(Topic::InterruptHandling.to_string(), "Interrupt Handling");
assert_eq!(
Topic::ProcessAndScheduling.to_string(),
"Process and Scheduling"
);
assert_eq!(Topic::Filesystems.to_string(), "Filesystems");
}
#[test]
fn topic_display_language_design_topics() {
assert_eq!(
Topic::OwnershipAndBorrowing.to_string(),
"Ownership and Borrowing"
);
assert_eq!(
Topic::TraitAndTypeclassSystems.to_string(),
"Trait and Typeclass Systems"
);
assert_eq!(Topic::MacroSystems.to_string(), "Macro Systems");
assert_eq!(Topic::ModuleSystems.to_string(), "Module Systems");
}
#[test]
fn topic_display_high_value_topics() {
assert_eq!(
Topic::InstructionEncoding.to_string(),
"Instruction Encoding"
);
assert_eq!(
Topic::ElfAndExecutableFormats.to_string(),
"ELF and Executable Formats"
);
assert_eq!(Topic::Allocators.to_string(), "Allocators");
assert_eq!(Topic::BootAndStartup.to_string(), "Boot and Startup");
}
#[test]
fn topic_serde_roundtrip_all_variants() {
let topics = [
Topic::DataTypes,
Topic::Concurrency,
Topic::ErrorHandling,
Topic::MemoryManagement,
Topic::InputOutput,
Topic::Testing,
Topic::Algorithms,
Topic::Patterns,
Topic::TypeSystems,
Topic::Performance,
Topic::Security,
Topic::KernelTopics,
Topic::QuantumComputing,
Topic::CompilerBootstrapping,
Topic::BinaryFormats,
Topic::LexingAndParsing,
Topic::IntermediateRepresentations,
Topic::CodeGeneration,
Topic::LinkingAndLoading,
Topic::OptimizationPasses,
Topic::SyscallsAndAbi,
Topic::VirtualMemory,
Topic::InterruptHandling,
Topic::ProcessAndScheduling,
Topic::Filesystems,
Topic::OwnershipAndBorrowing,
Topic::TraitAndTypeclassSystems,
Topic::MacroSystems,
Topic::ModuleSystems,
Topic::InstructionEncoding,
Topic::ElfAndExecutableFormats,
Topic::Allocators,
Topic::BootAndStartup,
];
for topic in &topics {
let json = serde_json::to_string(topic).unwrap();
let decoded: Topic = serde_json::from_str(&json).unwrap();
assert_eq!(topic, &decoded, "serde roundtrip failed for {}", topic);
}
}
#[test]
fn topic_display_is_nonempty_for_all() {
let topics = [
Topic::DataTypes,
Topic::LexingAndParsing,
Topic::CodeGeneration,
Topic::SyscallsAndAbi,
Topic::Allocators,
Topic::BootAndStartup,
Topic::Filesystems,
Topic::MacroSystems,
];
for topic in &topics {
let display = topic.to_string();
assert!(!display.is_empty(), "{:?} has empty display", topic);
assert!(
!display.contains("Topic::"),
"{:?} display looks like Debug",
topic
);
}
}
#[test]
fn gotcha_fields() {
let g = &sample_concept().gotchas[0];
assert!(g.bad_example.is_some());
assert!(g.good_example.is_some());
assert_eq!(g.language, Some(Language::Rust));
}
#[test]
fn performance_note_fields() {
let p = &sample_concept().performance_notes[0];
assert!(p.evidence.is_some());
assert_eq!(p.language, Some(Language::Rust));
}
#[test]
fn best_practice_universal() {
let bp = &sample_concept().best_practices[0];
assert!(bp.language.is_none()); }
}