1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Crate-wide error types.
use crate::validate::ValidationReport;
use crate::version::RdmlVersion;
/// Convenience alias for `Result<T, rdml_qpcr::Error>`.
pub type Result<T> = std::result::Result<T, Error>;
/// The error type for reading, writing, and validating RDML files.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
/// An underlying I/O operation failed.
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
/// The zip archive could not be read or written.
#[error("zip archive error: {0}")]
Zip(#[from] zip::result::ZipError),
/// The XML could not be tokenised at all (malformed markup).
#[error("malformed XML: {0}")]
Xml(#[from] quick_xml::Error),
/// The file is not valid UTF-8. RDML requires UTF-8 encoding.
#[error("RDML data is not valid UTF-8 (the format requires UTF-8): {0}")]
NotUtf8(#[from] std::str::Utf8Error),
/// The input is not an RDML document.
#[error("not an RDML document: {reason}")]
NotRdml {
/// What disqualified the input: a wrong root element name, or no
/// XML root element at all.
reason: String,
},
/// The root element carries a `version` attribute this crate does not know.
#[error("unsupported RDML version `{0}` (supported: 1.0, 1.1, 1.2, 1.3, 1.4)")]
UnsupportedVersion(String),
/// The root element carries no `version` attribute.
#[error("RDML root element has no `version` attribute")]
MissingVersion,
/// Writing was requested for a version this crate cannot emit.
///
/// Only RDML 1.0 is affected: its `pcrFormat`/`react@id` structure is a
/// different document shape that the consortium's own tooling treats as
/// legacy. See the crate docs on versions.
#[error("cannot write RDML {0}: this crate reads 1.0 but only writes 1.1–1.4")]
UnsupportedWriteVersion(RdmlVersion),
/// The XML was well-formed but did not match the RDML structure.
///
/// `path` is a human-readable location such as
/// `rdml/experiment[id=exp1]/run[id=run1]/react[3]/data[1]/cq`.
#[error("invalid RDML at {path}: {message}")]
Invalid {
/// Location of the offending content within the document.
path: String,
/// What was wrong with it.
message: String,
},
/// A value failed the constraints of its type (empty id, bad IUPAC
/// sequence, malformed date-time, …).
#[error("invalid value: {0}")]
InvalidValue(String),
/// The document failed [`validate`](crate::Rdml::validate) before
/// writing. Contains every problem found, not just the first.
#[error("document failed validation with {} error(s); first: {}",
.0.errors().count(),
.0.errors().next().map(ToString::to_string).unwrap_or_default())]
Validation(ValidationReport),
/// A digital-PCR partition table (TSV sidecar) was malformed.
#[error("invalid partition table {name}: line {line}: {message}")]
PartitionTable {
/// Archive member name of the table.
name: String,
/// 1-based line number of the offending row (0 for the header).
line: usize,
/// What was wrong.
message: String,
},
/// The requested archive member does not exist.
#[error("no such archive member: {0}")]
NoSuchMember(String),
}