1use std::{fmt::Write, path::PathBuf};
2
3use miette::{IntoDiagnostic, Result};
4use watchexec::paths::summarise_events_to_env;
5use watchexec_events::{filekind::FileEventKind, Event, Tag};
6
7use crate::{args::command::EnvVar, state::RotatingTempFile};
8
9pub fn emits_to_environment(events: &[Event]) -> impl Iterator<Item = EnvVar> {
10 summarise_events_to_env(events.iter())
11 .into_iter()
12 .map(|(k, value)| EnvVar {
13 key: format!("WATCHEXEC_{k}_PATH"),
14 value,
15 })
16}
17
18pub fn events_to_simple_format(events: &[Event]) -> Result<String> {
19 let mut buf = String::new();
20 for event in events {
21 let feks = event
22 .tags
23 .iter()
24 .filter_map(|tag| match tag {
25 Tag::FileEventKind(kind) => Some(kind),
26 _ => None,
27 })
28 .collect::<Vec<_>>();
29
30 for path in event.paths().map(|(p, _)| p) {
31 if feks.is_empty() {
32 writeln!(&mut buf, "other:{}", path.to_string_lossy()).into_diagnostic()?;
33 continue;
34 }
35
36 for fek in &feks {
37 writeln!(
38 &mut buf,
39 "{}:{}",
40 match fek {
41 FileEventKind::Any | FileEventKind::Other => "other",
42 FileEventKind::Access(_) => "access",
43 FileEventKind::Create(_) => "create",
44 FileEventKind::Modify(_) => "modify",
45 FileEventKind::Remove(_) => "remove",
46 },
47 path.to_string_lossy()
48 )
49 .into_diagnostic()?;
50 }
51 }
52 }
53
54 Ok(buf)
55}
56
57pub fn emits_to_file(target: &RotatingTempFile, events: &[Event]) -> Result<PathBuf> {
58 target.rotate()?;
59 target.write(events_to_simple_format(events)?.as_bytes())?;
60 Ok(target.path())
61}
62
63pub fn emits_to_json_file(target: &RotatingTempFile, events: &[Event]) -> Result<PathBuf> {
64 target.rotate()?;
65 for event in events {
66 if event.is_empty() {
67 continue;
68 }
69
70 target.write(&serde_json::to_vec(event).into_diagnostic()?)?;
71 target.write(b"\n")?;
72 }
73 Ok(target.path())
74}