11use super :: payload;
2- use chain_crypto:: { Ed25519Extended , SecretKey } ;
3- use color_eyre:: Report ;
4- use image:: { DynamicImage , ImageBuffer , Luma } ;
2+ use chain_crypto:: { Ed25519Extended , SecretKey , SecretKeyError } ;
3+ use image:: { DynamicImage , ImageBuffer , ImageError , Luma } ;
54use qrcode:: {
65 render:: { svg, unicode} ,
76 EcLevel , QrCode ,
87} ;
98use std:: fmt;
109use std:: fs:: File ;
11- use std:: io:: prelude:: * ;
10+ use std:: io:: { self , prelude:: * } ;
1211use std:: path:: Path ;
12+ use symmetric_cipher:: Error as SymmetricCipherError ;
13+ use thiserror:: Error ;
1314
1415pub struct KeyQrCode {
1516 inner : QrCode ,
1617}
1718
19+ #[ derive( Error , Debug ) ]
20+ pub enum KeyQrCodeError {
21+ #[ error( "encryption-decryption protocol error" ) ]
22+ SymmetricCipher ( #[ from] SymmetricCipherError ) ,
23+ #[ error( "io error" ) ]
24+ Io ( #[ from] io:: Error ) ,
25+ #[ error( "invalid secret key" ) ]
26+ SecretKey ( #[ from] SecretKeyError ) ,
27+ #[ error( "couldn't decode QR code" ) ]
28+ QrDecodeError ( #[ from] QrDecodeError ) ,
29+ #[ error( "failed to decode hex" ) ]
30+ HexDecodeError ( #[ from] hex:: FromHexError ) ,
31+ #[ error( "failed to decode hex" ) ]
32+ QrCodeHashError ( #[ from] super :: payload:: Error ) ,
33+ #[ error( transparent) ]
34+ Image ( #[ from] ImageError ) ,
35+ }
36+
37+ #[ derive( Error , Debug ) ]
38+ pub enum QrDecodeError {
39+ #[ error( "couldn't decode QR code" ) ]
40+ DecodeError ( #[ from] quircs:: DecodeError ) ,
41+ #[ error( "couldn't extract QR code" ) ]
42+ ExtractError ( #[ from] quircs:: ExtractError ) ,
43+ #[ error( "QR code payload is not valid uf8" ) ]
44+ NonUtf8Payload ,
45+ }
46+
1847impl KeyQrCode {
1948 pub fn generate ( key : SecretKey < Ed25519Extended > , password : & [ u8 ] ) -> Self {
2049 let enc_hex = payload:: generate ( key, password) ;
@@ -23,7 +52,7 @@ impl KeyQrCode {
2352 KeyQrCode { inner }
2453 }
2554
26- pub fn write_svg ( & self , path : impl AsRef < Path > ) -> Result < ( ) , Report > {
55+ pub fn write_svg ( & self , path : impl AsRef < Path > ) -> Result < ( ) , KeyQrCodeError > {
2756 let mut out = File :: create ( path) ?;
2857 let svg_file = self
2958 . inner
@@ -46,20 +75,23 @@ impl KeyQrCode {
4675 pub fn decode (
4776 img : DynamicImage ,
4877 password : & [ u8 ] ,
49- ) -> Result < Vec < SecretKey < Ed25519Extended > > , Report > {
78+ ) -> Result < Vec < SecretKey < Ed25519Extended > > , KeyQrCodeError > {
5079 let mut decoder = quircs:: Quirc :: default ( ) ;
5180
5281 let img = img. into_luma8 ( ) ;
5382
5483 let codes = decoder. identify ( img. width ( ) as usize , img. height ( ) as usize , & img) ;
5584
5685 codes
57- . map ( |code| -> Result < _ , Report > {
58- let decoded = code?. decode ( ) ?;
86+ . map ( |code| -> Result < _ , KeyQrCodeError > {
87+ let decoded = code
88+ . map_err ( QrDecodeError :: ExtractError )
89+ . and_then ( |c| c. decode ( ) . map_err ( QrDecodeError :: DecodeError ) ) ?;
5990
6091 // TODO: I actually don't know if this can fail
61- let h = std:: str:: from_utf8 ( & decoded. payload ) ?;
62- payload:: decode ( h, password)
92+ let h = std:: str:: from_utf8 ( & decoded. payload )
93+ . map_err ( |_| QrDecodeError :: NonUtf8Payload ) ?;
94+ payload:: decode ( h, password) . map_err ( Into :: into)
6395 } )
6496 . collect ( )
6597 }
0 commit comments