worktree_io/
repo_hooks_parse.rs1use crate::repo_hooks::{HookOrder, RepoConfig, RepoHookEntry, RepoHooksConfig};
17
18pub fn parse(contents: &str) -> Result<RepoConfig, String> {
25 let table: toml::Table = toml::from_str(contents).map_err(|e| e.to_string())?;
26 let mut hooks = RepoHooksConfig::default();
27 take_hooks(&table, &mut hooks)?;
28 if let Some(h) = table.get("hooks") {
29 let h = h
30 .as_table()
31 .ok_or_else(|| "`hooks` must be a TOML table".to_owned())?;
32 take_hooks(h, &mut hooks)?;
33 }
34 Ok(RepoConfig { hooks })
35}
36
37fn take_hooks(table: &toml::Table, out: &mut RepoHooksConfig) -> Result<(), String> {
38 if let Some(e) = extract_hook(table, "pre:open")? {
39 out.pre_open = Some(e);
40 }
41 if let Some(e) = extract_hook(table, "post:open")? {
42 out.post_open = Some(e);
43 }
44 Ok(())
45}
46
47fn extract_hook(table: &toml::Table, name: &str) -> Result<Option<RepoHookEntry>, String> {
48 let Some(script) = table.get(name) else {
49 return Ok(None);
50 };
51 let script = script
52 .as_str()
53 .ok_or_else(|| format!("`{name}` must be a string"))?;
54 let order_key = format!("{name}:order");
55 let order = match table.get(&order_key) {
56 None => HookOrder::default(),
57 Some(v) => {
58 let s = v
59 .as_str()
60 .ok_or_else(|| format!("`{order_key}` must be a string"))?;
61 parse_order(s).ok_or_else(|| {
62 format!("invalid `{order_key}` value `{s}` (expected before/after/replace)")
63 })?
64 }
65 };
66 Ok(Some(RepoHookEntry {
67 script: script.to_owned(),
68 order,
69 }))
70}
71
72fn parse_order(s: &str) -> Option<HookOrder> {
73 match s {
74 "before" => Some(HookOrder::Before),
75 "after" => Some(HookOrder::After),
76 "replace" => Some(HookOrder::Replace),
77 _ => None,
78 }
79}
80
81#[cfg(test)]
82#[path = "repo_hooks_parse_tests.rs"]
83mod tests;