quarto_source_map/
file_origin.rs1use serde::{Deserialize, Serialize};
13use std::fmt;
14
15#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21#[serde(tag = "kind", rename_all = "snake_case")]
22#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
23pub enum FileOrigin {
24 NotebookCell {
26 notebook_path: String,
29 cell_index: usize,
32 cell_id: Option<String>,
35 cell_type: String,
37 },
38}
39
40impl fmt::Display for FileOrigin {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match self {
43 FileOrigin::NotebookCell {
44 notebook_path,
45 cell_index,
46 cell_type,
47 ..
48 } => write!(f, "{notebook_path}[cell {cell_index}, {cell_type}]"),
49 }
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 fn origin() -> FileOrigin {
58 FileOrigin::NotebookCell {
59 notebook_path: "notebook.ipynb".into(),
60 cell_index: 2,
61 cell_id: Some("abc123".into()),
62 cell_type: "markdown".into(),
63 }
64 }
65
66 #[test]
67 fn display_is_the_cell_qualified_label() {
68 assert_eq!(origin().to_string(), "notebook.ipynb[cell 2, markdown]");
69 }
70
71 #[test]
72 fn display_omits_cell_id() {
73 let no_id = FileOrigin::NotebookCell {
76 notebook_path: "notebook.ipynb".into(),
77 cell_index: 2,
78 cell_id: None,
79 cell_type: "markdown".into(),
80 };
81 assert_eq!(no_id.to_string(), origin().to_string());
82 }
83
84 #[test]
85 fn serde_round_trip_keeps_all_fields() {
86 let json = serde_json::to_string(&origin()).unwrap();
87 assert_eq!(
88 json,
89 r#"{"kind":"notebook_cell","notebook_path":"notebook.ipynb","cell_index":2,"cell_id":"abc123","cell_type":"markdown"}"#
90 );
91 let back: FileOrigin = serde_json::from_str(&json).unwrap();
92 assert_eq!(back, origin());
93 }
94
95 #[test]
96 fn serde_round_trip_without_cell_id() {
97 let o = FileOrigin::NotebookCell {
98 notebook_path: "n.ipynb".into(),
99 cell_index: 7,
100 cell_id: None,
101 cell_type: "code".into(),
102 };
103 let back: FileOrigin = serde_json::from_str(&serde_json::to_string(&o).unwrap()).unwrap();
104 assert_eq!(back, o);
105 }
106}