feat(core): add csv dep + import error variants

Adds csv = "1" to relicario-core; introduces
ImportCsvHeader and ImportCsvFormat. Foundation for the
import_lastpass module landing in Task 2.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-29 22:47:06 -04:00
parent b7180e70f9
commit 768f0d39a5
3 changed files with 51 additions and 0 deletions

View File

@@ -51,6 +51,17 @@ pub enum RelicarioError {
#[error("backup envelope schema v{found}; this relicario reads v{expected}")]
BackupSchemaMismatch { found: u32, expected: u32 },
/// CSV header doesn't match the LastPass column layout.
#[error("unrecognized CSV header — expected LastPass export format ({0})")]
ImportCsvHeader(String),
/// CSV body could not be parsed (mismatched quoting, encoding, etc.).
/// Per-row record errors that the importer recovers from become
/// `ImportWarning` entries — this variant is reserved for failures
/// that abort the whole import.
#[error("CSV parse failed: {0}")]
ImportCsvFormat(String),
/// An item was looked up by ID but does not exist in the manifest.
#[error("item not found: {0}")]
ItemNotFound(String),
@@ -156,4 +167,15 @@ mod tests {
let s = format!("{}", schema);
assert!(s.contains("v2") && s.contains("v1"));
}
#[test]
fn import_errors_carry_useful_messages() {
let h = RelicarioError::ImportCsvHeader("missing 'name' column".into());
assert!(format!("{}", h).contains("LastPass"));
assert!(format!("{}", h).contains("missing 'name'"));
let f = RelicarioError::ImportCsvFormat("unterminated quote at line 12".into());
assert!(format!("{}", f).contains("CSV parse failed"));
assert!(format!("{}", f).contains("unterminated quote"));
}
}