impl FileSystemState {
pub fn validate_with_workspace(
&self,
workspace: &dyn Workspace,
executor: Option<&dyn ProcessExecutor>,
) -> Vec<ValidationError> {
let errors: Vec<ValidationError> = self
.files
.iter()
.filter_map(|(path, snapshot)| {
Self::validate_file_with_workspace(workspace, path, snapshot).err()
})
.chain(executor.and_then(|exec| self.validate_git_state_with_executor(exec).err()))
.collect();
errors
}
fn validate_file_with_workspace(
workspace: &dyn Workspace,
path: &str,
snapshot: &FileSnapshot,
) -> Result<(), ValidationError> {
let path_ref = Path::new(path);
if snapshot.exists && !workspace.exists(path_ref) {
return Err(ValidationError::FileMissing {
path: path.to_string(),
});
}
if !snapshot.exists && workspace.exists(path_ref) {
return Err(ValidationError::FileUnexpectedlyExists {
path: path.to_string(),
});
}
if snapshot.exists && !snapshot.verify_with_workspace(workspace) {
return Err(ValidationError::FileContentChanged {
path: path.to_string(),
});
}
Ok(())
}
fn validate_git_state_with_executor(
&self,
executor: &dyn ProcessExecutor,
) -> Result<(), ValidationError> {
if let Some(expected_oid) = &self.git_head_oid {
if let Some(current_oid) = crate::checkpoint::git_capture::git_head_oid(executor) {
if current_oid != *expected_oid {
return Err(ValidationError::GitHeadChanged {
expected: crate::common::domain_types::GitOid::from(expected_oid.as_str()),
actual: crate::common::domain_types::GitOid::from(current_oid.as_str()),
});
}
}
}
Ok(())
}
}