55use std:: fmt:: Display ;
66use std:: str:: FromStr ;
77
8+ use sha2:: Digest ;
89use thiserror:: Error ;
910
1011#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
@@ -78,14 +79,14 @@ impl FromStr for Cid {
7879 type Err = CidParseError ;
7980
8081 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
81- if s . chars ( ) . next ( ) != Some ( 'b' ) {
82+ if !s . starts_with ( 'b' ) {
8283 return Err ( CidParseError :: InvalidEncoding ) ;
8384 }
8485 // TODO: verify lower case
8586
8687 // skip base encoding prefix
8788 let bytes = data_encoding:: BASE32_NOPAD_NOCASE
88- . decode ( & s[ 1 ..] . as_bytes ( ) )
89+ . decode ( & s. as_bytes ( ) [ 1 ..] )
8990 . map_err ( |_e| CidParseError :: InvalidEncoding ) ?;
9091
9192 Cid :: from_bytes ( & bytes)
@@ -126,6 +127,20 @@ impl Cid {
126127
127128 out
128129 }
130+
131+ pub fn digest_sha2 ( codec : Codec , data : impl AsRef < [ u8 ] > ) -> Self {
132+ Self {
133+ codec,
134+ hash : Multihash :: digest_sha2 ( data) ,
135+ }
136+ }
137+
138+ pub fn digest_blake3 ( codec : Codec , data : impl AsRef < [ u8 ] > ) -> Self {
139+ Self {
140+ codec,
141+ hash : Multihash :: digest_blake3 ( data) ,
142+ }
143+ }
129144}
130145
131146impl Display for Cid {
@@ -197,6 +212,16 @@ impl Multihash {
197212 }
198213 out
199214 }
215+
216+ pub fn digest_sha2 ( data : impl AsRef < [ u8 ] > ) -> Self {
217+ let hash = sha2:: Sha256 :: digest ( data) ;
218+ Self :: Sha2256 ( hash. into ( ) )
219+ }
220+
221+ pub fn digest_blake3 ( data : impl AsRef < [ u8 ] > ) -> Self {
222+ let hash = blake3:: hash ( data. as_ref ( ) ) ;
223+ Self :: Blake3 ( hash. into ( ) )
224+ }
200225}
201226
202227#[ cfg( test) ]
@@ -214,4 +239,28 @@ mod tests {
214239 let cid_str_back = parsed. to_string ( ) ;
215240 assert_eq ! ( cid_str_back, cid_str) ;
216241 }
242+
243+ #[ test]
244+ fn test_base_blake3 ( ) {
245+ // Blake3: "foo"
246+ let cid_str = "bafkr4iae4c5tt4yldi76xcpvg3etxykqkvec352im5fqbutolj2xo5yc5e" ;
247+ let parsed: Cid = cid_str. parse ( ) . unwrap ( ) ;
248+ assert_eq ! ( parsed. codec( ) , Codec :: Raw ) ;
249+ assert ! ( matches!( parsed. hash( ) , Multihash :: Blake3 ( _) ) ) ;
250+
251+ let cid_str_back = parsed. to_string ( ) ;
252+ assert_eq ! ( cid_str_back, cid_str) ;
253+ }
254+
255+ #[ test]
256+ fn test_digest_sha2_256 ( ) {
257+ let cid_str = "bafkreibme22gw2h7y2h7tg2fhqotaqjucnbc24deqo72b6mkl2egezxhvy" ;
258+ assert_eq ! ( Cid :: digest_sha2( Codec :: Raw , b"foo" ) . to_string( ) , cid_str) ;
259+ }
260+
261+ #[ test]
262+ fn test_digest_blake3 ( ) {
263+ let cid_str = "bafkr4iae4c5tt4yldi76xcpvg3etxykqkvec352im5fqbutolj2xo5yc5e" ;
264+ assert_eq ! ( Cid :: digest_blake3( Codec :: Raw , b"foo" ) . to_string( ) , cid_str) ;
265+ }
217266}
0 commit comments