1use std::io::Write;
2
3use crate::error::chronicle_error::GitSnafu;
4use crate::error::Result;
5use crate::git::GitOps;
6use serde::{Deserialize, Serialize};
7use snafu::ResultExt;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ExportEntry {
15 pub commit_sha: String,
16 pub timestamp: String,
17 pub annotation: serde_json::Value,
18}
19
20pub fn export_annotations<W: Write>(git_ops: &dyn GitOps, writer: &mut W) -> Result<usize> {
25 let note_list = git_ops.list_annotated_commits(u32::MAX).context(GitSnafu)?;
26 let mut count = 0;
27
28 for sha in ¬e_list {
29 let note_content = match git_ops.note_read(sha).context(GitSnafu)? {
30 Some(content) => content,
31 None => continue,
32 };
33
34 let annotation: serde_json::Value = match serde_json::from_str(¬e_content) {
35 Ok(a) => a,
36 Err(_) => continue, };
38
39 let timestamp = annotation
40 .get("timestamp")
41 .and_then(|t| t.as_str())
42 .unwrap_or("")
43 .to_string();
44
45 let entry = ExportEntry {
46 commit_sha: sha.clone(),
47 timestamp,
48 annotation,
49 };
50
51 let line =
52 serde_json::to_string(&entry).map_err(|e| crate::error::ChronicleError::Json {
53 source: e,
54 location: snafu::Location::default(),
55 })?;
56
57 writeln!(writer, "{line}").map_err(|e| crate::error::ChronicleError::Io {
58 source: e,
59 location: snafu::Location::default(),
60 })?;
61
62 count += 1;
63 }
64
65 Ok(count)
66}