feat(p10-1a-2): map SourceSpan::Code -> Citation::Code in citation_helper

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-19 15:59:03 +00:00
parent 9f3edb7e24
commit 42712b50c2

View File

@@ -49,12 +49,12 @@ pub(crate) fn citation_from_first_span(
end_ms: *end_ms,
speaker: None,
},
// TODO(p10-1a-2 Task 3): map to Citation::Code
Some(SourceSpan::Code { .. }) => Citation::Line {
Some(SourceSpan::Code { line_start, line_end, symbol, lang }) => Citation::Code {
path,
start: 1,
end: 1,
section,
line_start: *line_start,
line_end: *line_end,
symbol: symbol.clone(),
lang: lang.clone(),
},
// Byte-spans don't have a Citation variant. Fall back to a
// Line citation pointing at the document head — better than
@@ -79,3 +79,43 @@ pub(crate) fn citation_from_first_span(
}
}
}
#[cfg(test)]
mod tests {
use kebab_core::{Citation, SourceSpan, WorkspacePath};
#[test]
fn build_citation_code_maps_symbol_and_lang() {
let span = SourceSpan::Code {
line_start: 5,
line_end: 30,
symbol: Some("chunk::md_heading_v1::MdHeadingV1Chunker::chunk".into()),
lang: Some("rust".into()),
};
let c = super::citation_from_first_span(
"c1",
WorkspacePath::new("crates/kebab-chunk/src/md_heading_v1.rs".to_string()).unwrap(),
None,
Some(&span),
);
match c {
Citation::Code {
path,
line_start,
line_end,
symbol,
lang,
} => {
assert_eq!(path.0, "crates/kebab-chunk/src/md_heading_v1.rs");
assert_eq!(line_start, 5);
assert_eq!(line_end, 30);
assert_eq!(
symbol.as_deref(),
Some("chunk::md_heading_v1::MdHeadingV1Chunker::chunk")
);
assert_eq!(lang.as_deref(), Some("rust"));
}
other => panic!("expected Citation::Code, got {other:?}"),
}
}
}