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:
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user