1use std::io;
2
3use thiserror::Error;
4
5use crate::FileDigestAlgorithm;
6
7#[derive(Error, Debug)]
8#[non_exhaustive]
9pub enum RPMError {
10 #[error(transparent)]
11 Io(#[from] io::Error),
12
13 #[error(transparent)]
14 Hex(#[from] hex::FromHexError),
15
16 #[error("{0}")]
17 Nom(String),
18 #[error(
19 "invalid magic expected: {expected} but got: {actual} - whole input was {complete_input:?}"
20 )]
21 InvalidMagic {
22 expected: u8,
23 actual: u8,
24 complete_input: Vec<u8>,
25 },
26 #[error("unsupported Version {0} - only header version 1 is supported")]
27 UnsupportedHeaderVersion(u8),
28 #[error("invalid tag {raw_tag} for store {store_type}")]
29 InvalidTag {
30 raw_tag: u32,
31 store_type: &'static str,
32 },
33 #[error("invalid tag data type in store {store_type}: expected 0 - 9 but got {raw_data_type}")]
34 InvalidTagDataType {
35 raw_data_type: u32,
36 store_type: &'static str,
37 },
38 #[error("unable to find tag {0}")]
39 TagNotFound(String),
40 #[error("tag {tag} has data type {actual_data_type}, not {expected_data_type}")]
41 UnexpectedTagDataType {
42 expected_data_type: &'static str,
43 actual_data_type: String,
44 tag: String,
45 },
46 #[error("invalid tag array index {tag} with {index} while bounded at {bound}")]
47 InvalidTagIndex { tag: String, index: u32, bound: u32 },
48
49 #[error("invalid tag value enum varaint for {tag} with {variant}")]
50 InvalidTagValueEnumVariant { tag: String, variant: u32 },
51
52 #[error("unsupported lead major version {0} - only version 3 is supported")]
53 InvalidLeadMajorVersion(u8),
54
55 #[error("unsupported lead major version {0} - only version 0 is supported")]
56 InvalidLeadMinorVersion(u8),
57
58 #[error("invalid type - expected 0 or 1 but got {0}")]
59 InvalidLeadPKGType(u16),
60
61 #[error("invalid os-type - expected 1 but got {0}")]
62 InvalidLeadOSType(u16),
63
64 #[error("invalid signature-type - expected 5 but got {0}")]
65 InvalidLeadSignatureType(u16),
66
67 #[error("invalid size of reserved area - expected length of {expected} but got {actual}")]
68 InvalidReservedSpaceSize { expected: u16, actual: usize },
69
70 #[error("invalid destination path {path} - {desc}")]
71 InvalidDestinationPath { path: String, desc: &'static str },
72
73 #[error("signature packet not found in what is supposed to be a signature")]
74 NoSignatureFound,
75
76 #[error("error creating signature: {0}")]
77 SignError(Box<dyn std::error::Error>),
78
79 #[error("error parsing key - {details}. underlying error was: {source}")]
80 KeyLoadError {
81 source: Box<dyn std::error::Error>,
82 details: &'static str,
83 },
84
85 #[error("error verifying signature with key {key_ref}: {source}")]
86 VerificationError {
87 source: Box<dyn std::error::Error>,
88 key_ref: String,
89 },
90
91 #[error("unable to find key with key-ref: {key_ref}")]
92 KeyNotFoundError { key_ref: String },
93
94 #[error("unknown compressor type {0} - only gzip and none are supported")]
95 UnknownCompressorType(String),
96
97 #[error("unsupported file digest algorithm {0:?}")]
98 UnsupportedFileDigestAlgorithm(FileDigestAlgorithm),
99
100 #[error("invalid file mode {raw_mode} - {reason}")]
101 InvalidFileMode { raw_mode: i32, reason: &'static str },
102}
103
104impl From<nom::Err<(&[u8], nom::error::ErrorKind)>> for RPMError {
105 fn from(error: nom::Err<(&[u8], nom::error::ErrorKind)>) -> Self {
106 match error {
107 nom::Err::Error((_, kind)) | nom::Err::Failure((_, kind)) => {
108 RPMError::Nom(kind.description().to_string())
109 }
110 nom::Err::Incomplete(_) => RPMError::Nom("unhandled incomplete".to_string()),
111 }
112 }
113}