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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
use core::{error::Error, fmt};
#[cfg(feature = "std")]
use std::io;
#[cfg(feature = "micro-qr")]
use crate::{SymbolErrorCorrection, SymbolVersion};
/// Errors returned while encoding a QR Code symbol.
#[derive(Debug)]
#[non_exhaustive]
pub enum EncodeError {
/// The encoded bit stream exceeds the selected symbol capacity.
DataTooLong {
/// The exact number of bits the encoded data needs, or `None` when the encoder rejected the input before measuring it, for example from a capacity precheck or a character count over the indicator limit.
required_bits: Option<usize>,
/// The number of data bits the selected symbols hold.
capacity_bits: usize,
},
/// The input contains a byte that is not valid for the requested mode.
InvalidData {
/// The name of the requested mode.
mode: &'static str,
/// The byte offset of the first invalid character in the input.
byte_offset: usize,
},
/// The input cannot be represented by the selected symbol family.
#[cfg(feature = "micro-qr")]
TextNotRepresentable {
/// The byte offset of the character that cannot be represented.
byte_offset: usize,
/// The name of the symbol family.
family: &'static str,
},
/// The ECI assignment is outside the range supported by QR Code.
#[cfg(any(feature = "qr", feature = "rmqr"))]
InvalidEciAssignment(u32),
/// The FNC1 second-position application indicator is invalid.
#[cfg(any(feature = "qr", feature = "rmqr"))]
InvalidApplicationIndicator,
/// The selected version range is empty or invalid.
InvalidVersionRange,
/// The selected symbol family does not support a requested mode.
#[cfg(feature = "micro-qr")]
UnsupportedMode {
/// The name of the unsupported mode.
mode: &'static str,
/// The name of the symbol family or version.
family: &'static str,
},
/// The selected version does not support the requested error correction level.
#[cfg(feature = "micro-qr")]
UnsupportedErrorCorrection {
/// The selected version.
version: SymbolVersion,
/// The requested error correction level.
error_correction: SymbolErrorCorrection,
},
/// The requested mask number is outside the supported range.
InvalidMask,
/// A Structured Append sequence has fewer than one or more than 16 parts.
#[cfg(feature = "qr")]
InvalidStructuredAppendPartCount {
/// The number of parts that was given.
count: usize,
},
}
impl fmt::Display for EncodeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::DataTooLong {
required_bits,
capacity_bits,
} => {
if let Some(required_bits) = required_bits {
write!(
f,
"the encoded data needs {required_bits} bits but the selected symbols \
hold {capacity_bits} bits"
)
} else {
f.write_str("the encoded data exceeds the capacity of the selected symbols")
}
},
Self::InvalidData {
mode,
byte_offset,
} => {
write!(f, "invalid {mode} data at byte offset {byte_offset}")
},
#[cfg(feature = "micro-qr")]
Self::TextNotRepresentable {
byte_offset,
family,
} => {
write!(
f,
"the input at byte offset {byte_offset} cannot be represented by {family}"
)
},
#[cfg(any(feature = "qr", feature = "rmqr"))]
Self::InvalidEciAssignment(value) => {
write!(f, "ECI assignment {value} is outside 0..=999999")
},
#[cfg(any(feature = "qr", feature = "rmqr"))]
Self::InvalidApplicationIndicator => f.write_str("invalid FNC1 application indicator"),
Self::InvalidVersionRange => f.write_str("invalid symbol version range"),
#[cfg(feature = "micro-qr")]
Self::UnsupportedMode {
mode,
family,
} => {
write!(f, "{mode} mode is not supported by {family}")
},
#[cfg(feature = "micro-qr")]
Self::UnsupportedErrorCorrection {
version,
error_correction,
} => write!(f, "{error_correction:?} error correction is not supported by {version:?}"),
Self::InvalidMask => f.write_str("the mask number is outside the supported range"),
#[cfg(feature = "qr")]
Self::InvalidStructuredAppendPartCount {
count,
} => {
write!(f, "Structured Append requires 1..=16 parts, got {count}")
},
}
}
}
impl Error for EncodeError {}
/// Errors returned while rendering a QR Code symbol.
#[derive(Debug)]
#[non_exhaustive]
pub enum RenderError {
/// The requested output is too small for an integer module scale and quiet zone.
ImageSizeTooSmall,
/// The requested output dimensions overflow a supported image size.
ImageSizeTooLarge,
/// An input or output operation failed.
#[cfg(feature = "std")]
Io(io::Error),
#[cfg(feature = "image")]
/// PNG encoding failed.
Image(image::ImageError),
}
impl fmt::Display for RenderError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ImageSizeTooSmall => {
f.write_str("image size is too small to draw the whole symbol")
},
Self::ImageSizeTooLarge => f.write_str("image size is too large to generate"),
#[cfg(feature = "std")]
Self::Io(error) => fmt::Display::fmt(error, f),
#[cfg(feature = "image")]
Self::Image(error) => fmt::Display::fmt(error, f),
}
}
}
impl Error for RenderError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
#[cfg(feature = "std")]
Self::Io(error) => Some(error),
#[cfg(feature = "image")]
Self::Image(error) => Some(error),
_ => None,
}
}
}
#[cfg(feature = "std")]
impl From<io::Error> for RenderError {
#[inline]
fn from(error: io::Error) -> Self {
Self::Io(error)
}
}
#[cfg(feature = "image")]
impl From<image::ImageError> for RenderError {
#[inline]
fn from(error: image::ImageError) -> Self {
Self::Image(error)
}
}