1use crate::error::Result;
2use crate::git::CliOps;
3use crate::read::{execute, ReadQuery};
4use crate::schema::LineRange;
5
6pub fn run(path: String, anchor: Option<String>, lines: Option<String>) -> Result<()> {
7 let line_range = match lines {
8 Some(ref s) => Some(parse_line_range(s)?),
9 None => None,
10 };
11
12 let repo_dir = std::env::current_dir().map_err(|e| crate::error::ChronicleError::Io {
13 source: e,
14 location: snafu::Location::default(),
15 })?;
16 let git_ops = CliOps::new(repo_dir);
17
18 let query = ReadQuery {
19 file: path,
20 anchor,
21 lines: line_range,
22 };
23
24 let result = execute(&git_ops, &query)?;
25
26 let json =
27 serde_json::to_string_pretty(&result).map_err(|e| crate::error::ChronicleError::Json {
28 source: e,
29 location: snafu::Location::default(),
30 })?;
31 println!("{json}");
32
33 Ok(())
34}
35
36fn parse_line_range(s: &str) -> Result<LineRange> {
38 let parts: Vec<&str> = s.split(':').collect();
39 if parts.len() != 2 {
40 return Err(crate::error::ChronicleError::Config {
41 message: format!("invalid line range '{s}', expected format 'start:end'"),
42 location: snafu::Location::default(),
43 });
44 }
45 let start: u32 = parts[0]
46 .parse()
47 .map_err(|_| crate::error::ChronicleError::Config {
48 message: format!("invalid start line number '{}'", parts[0]),
49 location: snafu::Location::default(),
50 })?;
51 let end: u32 = parts[1]
52 .parse()
53 .map_err(|_| crate::error::ChronicleError::Config {
54 message: format!("invalid end line number '{}'", parts[1]),
55 location: snafu::Location::default(),
56 })?;
57 Ok(LineRange { start, end })
58}