credence_lib/configuration/
coordinate.rs1use super::{super::coordinator::*, error::*};
2
3use {
4 compris::resolve::*,
5 httpdate::*,
6 kutil_cli::debug::*,
7 kutil_http::*,
8 notify,
9 std::{io, path::*},
10};
11
12#[derive(Clone, Debug, Debuggable, Resolve)]
18pub struct CoordinateConfiguration {
19 #[resolve]
21 #[debuggable(iter(item), style(string))]
22 pub paths: Vec<PathBuf>,
23
24 #[resolve]
26 #[debuggable(option, style(string))]
27 pub coordinator: Option<PathBuf>,
28
29 #[resolve(key = "follow-symlinks")]
31 #[debuggable(style(symbol))]
32 pub follow_symlinks: bool,
33
34 #[resolve(key = "compare-contents")]
36 #[debuggable(style(symbol))]
37 pub compare_contents: bool,
38
39 #[resolve(key = "queue-size")]
41 #[debuggable(style(number))]
42 pub queue_size: usize,
43}
44
45impl CoordinateConfiguration {
46 pub fn validate<PathT>(&mut self, base_path: PathT, default_paths: Vec<PathBuf>) -> Result<(), ConfigurationError>
48 where
49 PathT: AsRef<Path>,
50 {
51 let base_path = base_path.as_ref();
52
53 if let Some(coordinator) = &self.coordinator {
54 if !coordinator.is_absolute() {
55 self.coordinator = Some(base_path.join(&coordinator));
56 }
57 }
58
59 if self.paths.is_empty() {
60 self.paths = default_paths;
61 } else {
62 let mut paths = Vec::with_capacity(self.paths.len());
63 for path in &self.paths {
64 paths.push(if path.is_absolute() { path.clone() } else { base_path.join(path) });
65 }
66 self.paths = paths;
67 }
68
69 Ok(())
70 }
71
72 pub fn new_coordinator(&self) -> notify::Result<Option<Coordinator>> {
74 Ok(if let Some(coordinator) = &self.coordinator {
75 if !self.paths.is_empty() {
76 let mut coordinator = Coordinator::new(
77 coordinator.clone(),
78 self.follow_symlinks,
79 self.compare_contents,
80 self.queue_size,
81 )?;
82
83 for path in &self.paths {
84 if path.exists() {
85 coordinator.add(path)?;
86 } else {
87 tracing::info!("path does not exist: {}", path.display());
88 }
89 }
90
91 Some(coordinator)
92 } else {
93 None
94 }
95 } else {
96 None
97 })
98 }
99
100 pub fn coordinator_modified(&self) -> io::Result<Option<HttpDate>> {
102 Ok(match &self.coordinator {
103 Some(coordinator) => {
104 if coordinator.exists() {
105 Some(file_modified(coordinator)?)
106 } else {
107 None
108 }
109 }
110 None => None,
111 })
112 }
113}
114
115impl Default for CoordinateConfiguration {
116 fn default() -> Self {
117 Self {
118 paths: Vec::default(),
119 coordinator: Some(PathBuf::from(".coordinator")),
120 follow_symlinks: true,
121 compare_contents: false,
122 queue_size: 128,
123 }
124 }
125}