#![allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum DocKind {
Type,
Syntax,
Handler,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Stability {
Stable,
Experimental,
}
impl Stability {
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Stable => "stable",
Self::Experimental => "experimental",
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct DocEntry {
pub name: &'static str,
pub kind: DocKind,
pub since: &'static str,
pub stability: Stability,
pub body: &'static str,
}
include!(concat!(env!("OUT_DIR"), "/generated.rs"));
#[must_use]
pub fn find_doc(name: &str, kind: DocKind) -> Option<&'static DocEntry> {
ENTRIES.iter().find(|e| e.name == name && e.kind == kind)
}
#[must_use]
pub fn find_any_doc(name: &str) -> Option<&'static DocEntry> {
ENTRIES.iter().find(|e| e.name == name)
}
#[must_use]
pub const fn entry_count() -> usize {
ENTRIES.len()
}
pub fn iter_entries() -> impl Iterator<Item = &'static DocEntry> {
ENTRIES.iter()
}
#[must_use]
pub fn render_doc(entry: &DocEntry) -> String {
let kind_label = match entry.kind {
DocKind::Type => "type",
DocKind::Syntax => "syntax",
DocKind::Handler => "handler",
};
format!(
"**{kind}** `{name}` · {stability} · since {since}\n\n---\n\n{body}",
kind = kind_label,
name = entry.name,
stability = entry.stability.label(),
since = entry.since,
body = entry.body,
)
}
#[cfg(test)]
mod tests {
use super::{
DocKind, Stability, entry_count, find_any_doc, find_doc, iter_entries, render_doc,
};
#[test]
fn corpus_is_non_empty() {
assert!(
entry_count() >= 10,
"expected at least 10 doc entries (sub-fase 0.g verification floor); got {}",
entry_count(),
);
}
#[test]
fn find_doc_pins_name_and_kind() {
let s = find_doc("String", DocKind::Type).expect("String type doc");
assert_eq!(s.name, "String");
assert_eq!(s.kind, DocKind::Type);
assert_eq!(s.stability, Stability::Stable);
assert!(!s.body.is_empty());
assert!(find_doc("String", DocKind::Syntax).is_none());
}
#[test]
fn find_any_doc_falls_through_kinds() {
let entry = find_any_doc("flow").expect("flow syntax doc");
assert_eq!(entry.kind, DocKind::Syntax);
}
#[test]
fn render_doc_includes_metadata_header() {
let s = find_doc("String", DocKind::Type).unwrap();
let md = render_doc(s);
assert!(md.starts_with("**type** `String`"));
assert!(md.contains("· stable"));
assert!(md.contains("· since"));
assert!(md.contains(s.body));
}
#[test]
fn iter_entries_yields_stable_order() {
let kinds: Vec<DocKind> = iter_entries().map(|e| e.kind).collect();
let mut sorted = kinds.clone();
sorted.sort();
assert_eq!(kinds, sorted, "iter_entries must yield stable order");
}
}