use rustledger_core::{Document, Note};
use std::path::Path;
use crate::LedgerState;
use crate::error::{ErrorCode, ValidationError};
pub fn validate_note(state: &LedgerState, note: &Note, errors: &mut Vec<ValidationError>) {
if !state.accounts.contains_key(¬e.account) {
errors.push(ValidationError::new(
ErrorCode::AccountNotOpen,
format!("Invalid reference to unknown account '{}'", note.account),
note.date,
));
}
}
pub fn validate_document(state: &LedgerState, doc: &Document, errors: &mut Vec<ValidationError>) {
if !state.accounts.contains_key(&doc.account) {
errors.push(ValidationError::new(
ErrorCode::AccountNotOpen,
format!("Invalid reference to unknown account '{}'", doc.account),
doc.date,
));
}
if state.options.check_documents {
let doc_path = Path::new(&doc.path);
let mut file_was_found = false;
let full_path = if doc_path.is_absolute() {
file_was_found = doc_path.exists();
doc_path.to_path_buf()
} else if let Some(base) = &state.options.document_base {
let p = base.join(doc_path);
file_was_found = p.exists();
p
} else if !state.options.document_dirs.is_empty() {
let mut found = None;
for dir in &state.options.document_dirs {
let candidate = dir.join(doc_path);
if candidate.exists() {
found = Some(candidate);
break;
}
}
match found {
Some(p) => {
file_was_found = true;
p
}
None => doc_path.to_path_buf(),
}
} else {
file_was_found = doc_path.exists();
doc_path.to_path_buf()
};
if !file_was_found {
let mut error = ValidationError::new(
ErrorCode::DocumentNotFound,
format!("Document file not found: {}", doc.path),
doc.date,
);
if doc_path.is_relative()
&& state.options.document_base.is_none()
&& !state.options.document_dirs.is_empty()
{
let searched: Vec<String> = state
.options
.document_dirs
.iter()
.map(|d| d.join(doc_path).display().to_string())
.collect();
error = error.with_context(format!("searched: {}", searched.join(", ")));
} else {
error = error.with_context(format!("resolved path: {}", full_path.display()));
}
errors.push(error);
}
}
}