spec_driven_docs/commands/
read.rs1use crate::cli::read::ReadArgs;
12use crate::context::AppContext;
13use crate::error::AppError;
14use crate::output;
15use crate::services::reader::{Shelf, get, list};
16
17pub fn run(_ctx: &AppContext, shelf: &Shelf, args: ReadArgs) -> Result<(), AppError> {
23 if args.list {
24 let names = list(shelf);
25 let width = names.iter().map(String::len).max().unwrap_or(0);
26 for name in names {
27 match crate::domain::docs_catalog::CATALOG.for_document(shelf.id, &name) {
28 Some(topic) => output::line(format!("{name:width$} {}", topic.summary)),
29 None => output::line(name),
30 }
31 }
32 return Ok(());
33 }
34 let Some(name) = args.name else {
35 return Err(AppError::Usage(
36 "a document name or --list is required".to_string(),
37 ));
38 };
39 let Some(text) = get(shelf, &name) else {
40 return Err(AppError::Usage(format!("no such document: {name}")));
41 };
42 output::line(text.trim_end_matches('\n'));
43 Ok(())
44}