@ -96,7 +96,6 @@ impl<H: Header +?Sized> SuperHeader<H>
let line = line . trim ( ) ;
trace ! ( "Read super-header line: {:?}" , line ) ;
let mut chunks = line . split_whitespace ( ) ;
let mut item = 0 ;
macro_rules! take_one {
( ) = > {
if let Some ( chunk ) = chunks . next ( ) {
@ -106,6 +105,7 @@ impl<H: Header +?Sized> SuperHeader<H>
. with_section ( | | format! ( "{:#?}" , chunks ) . header ( "Split section was" ) )
. with_note ( | | "Expect at least 6 items delimited by whitespace" ) ) ;
}
}
}
macro_rules! check_eq {
@ -114,27 +114,86 @@ impl<H: Header +?Sized> SuperHeader<H>
let val = $val ;
let chunk = take_one ! ( ) ;
if chunk ! = val {
return Err ( eyre ::eyre ! ( "Invalid data at index {}", item )
return Err ( eyre ::eyre ! ( "Invalid data at chunk {}", chunk )
. with_section ( | | format! ( "{:?}" , val ) . header ( "Expected" ) )
. with_section ( | | format! ( "{:?}" , chunk ) . header ( "Got" ) ) ) ;
}
item + = 1 ;
}
}
}
check_eq ! ( "---" ) ;
check_eq ! ( unsafe { std ::str ::from_utf8_unchecked ( & RAE_HEADER_BIT [ .. ] ) } ) ;
//TODO: Parse text version from hex encoded integer in `2`
let version = {
let enc_str = take_one ! ( ) ;
// Version should be encoded like: v0.0.0*-0 (v<version string>-<version number (hex)>)
todo! ( )
let mut spl = enc_str . split ( '-' ) . fuse ( ) ;
match ( spl . next ( ) , spl . next ( ) ) {
( None , _ ) = > Err ( eyre ::eyre ! ( "Cannot extract version" ) ) ,
( Some ( x ) , None ) = > Err ( eyre ::eyre ! ( "Cannot extract version integer" )
. with_section ( | | x . to_owned ( ) . header ( "Version part was" ) ) ) ,
( Some ( v ) , Some ( i ) ) = > {
trace ! ( "Found version string part {} and integer part {}" , v , i ) ;
match u32 ::from_str_radix ( i , 16 ) {
Ok ( i ) = > Version ::try_from_u32 ( i )
. wrap_err_with ( | | eyre ::eyre ! ( "Failed to convert integer part to version" ) )
. with_section ( | | i . to_string ( ) . header ( "Integer (decoeed u32) was" ) ) ,
Err ( x ) = > Err ( x ) . wrap_err_with ( | | eyre ::eyre ! ( "Failed to decode string part into integer" ) ) ,
} . with_section ( | | i . to_owned ( ) . header ( "Integer part was" ) )
. with_section ( | | v . to_owned ( ) . header ( "Version part was" ) )
. and_then ( | vers | {
let vstr = vers . to_string ( ) ;
if v . len ( ) < 1 {
Err ( eyre ::eyre ! ( "Embedded version string was invalid" ) )
. with_section ( | | v . to_owned ( ) . header ( "Embedded was" ) )
. with_section ( move | | vstr . header ( "Decoded was" ) )
}
else if vstr ! = & v [ 1 .. ] {
Err ( eyre ::eyre ! ( "Embedded version string does not match decoded version string" ) )
. with_section ( | | v . to_owned ( ) . header ( "Embedded was" ) )
. with_section ( move | | vstr . header ( "Decoded was" ) )
} else {
Ok ( vers )
}
} )
} ,
} . wrap_err_with ( | | eyre ::eyre ! ( "Failed to decode version" ) )
. with_section ( | | enc_str . to_owned ( ) . header ( "The version string was" ) ) ?
} ;
//Parse hash from hex encoded string `3`
let hash = {
let hash_str = take_one ! ( ) ;
let w = | | {
if hash_str . len ( ) < 2 {
return Err ( eyre ::eyre ! ( "Not long enough" ) )
}
let hash_str = & hash_str [ 1 .. ( hash_str . len ( ) - 1 ) ] ;
use hex ::FromHex ;
let bytes = < [ u8 ; crypto ::consts ::SHA256_SIZE ] > ::from_hex ( hash_str )
. wrap_err_with ( | | eyre ::eyre ! ( "Hex decode to {} size byte array failed" , crypto ::consts ::SHA256_SIZE ) )
. with_section ( | | hash_str . to_owned ( ) . header ( "Hash string (cut) was" ) ) ? ;
Ok ( unsafe { std ::mem ::transmute ::< _ , crypto ::sha256 ::Sha256Hash > ( bytes ) } ) //Sha256Hash is repr(transparent)
} ;
w ( )
. wrap_err_with ( | | eyre ::eyre ! ( "Failed to decode hash" ) )
. with_section ( | | hash_str . to_owned ( ) . header ( "The hash string was" ) ) ?
} ;
//TODO: Parse hash from hex encoded string `3`
check_eq ! ( H ::NAME ) ;
check_eq ! ( "---" ) ;
debug_assert_eq! ( item , 6 ) ;
todo! ( )
if version . should_warn ( & CURRENT_VERSION ) {
warn ! ( "Header is read to have deprecated version {}, we are on version {}" , version , CURRENT_VERSION )
}
Ok (
Self {
head : RAE_HEADER_BIT ,
vers : version ,
header_hash : hash ,
chk : H ::CHECK ,
_header : PhantomData ,
}
)
}
/// Write this superheader as bytes to this stream