18
18
#[ cfg( any( test, feature = "rand" ) ) ] use rand:: Rng ;
19
19
20
20
use core:: { fmt, ptr, str} ;
21
+ use core:: ops:: BitXor ;
21
22
22
23
use super :: { from_hex, Secp256k1 } ;
23
24
use super :: Error :: { self , InvalidPublicKey , InvalidPublicKeySum , InvalidSecretKey } ;
@@ -890,7 +891,7 @@ impl XOnlyPublicKey {
890
891
return Err ( Error :: InvalidPublicKey ) ;
891
892
}
892
893
893
- Ok ( parity. into ( ) )
894
+ Parity :: from_i32 ( parity)
894
895
}
895
896
}
896
897
@@ -918,7 +919,7 @@ impl XOnlyPublicKey {
918
919
let err = ffi:: secp256k1_xonly_pubkey_tweak_add_check (
919
920
secp. ctx ,
920
921
tweaked_ser. as_c_ptr ( ) ,
921
- tweaked_parity. into ( ) ,
922
+ tweaked_parity. to_i32 ( ) ,
922
923
& self . 0 ,
923
924
tweak. as_c_ptr ( ) ,
924
925
) ;
@@ -928,27 +929,77 @@ impl XOnlyPublicKey {
928
929
}
929
930
}
930
931
931
- /// Opaque type used to hold the parity passed between FFI function calls.
932
+ /// Represents the parity passed between FFI function calls.
932
933
#[ derive( Copy , Clone , PartialEq , Eq , Debug , PartialOrd , Ord , Hash ) ]
933
- pub struct Parity ( i32 ) ;
934
+ pub enum Parity {
935
+ /// Even parity.
936
+ Even = 0 ,
937
+ /// Odd parity.
938
+ Odd = 1 ,
939
+ }
940
+
941
+ impl Parity {
942
+ /// Converts parity into a integer (byte) value.
943
+ pub fn to_u8 ( self ) -> u8 {
944
+ self as u8
945
+ }
946
+
947
+ /// Converts parity into a integer value.
948
+ pub fn to_i32 ( self ) -> i32 {
949
+ self as i32
950
+ }
951
+
952
+ /// Constructs a [`Parity`] from a byte.
953
+ pub fn from_u8 ( parity : u8 ) -> Result < Parity , Error > {
954
+ Parity :: from_i32 ( parity as i32 )
955
+ }
956
+
957
+ /// Constructs a [`Parity`] from a signed integer.
958
+ pub fn from_i32 ( parity : i32 ) -> Result < Parity , Error > {
959
+ match parity {
960
+ 0 => Ok ( Parity :: Even ) ,
961
+ 1 => Ok ( Parity :: Odd ) ,
962
+ _ => Err ( Error :: InvalidParityValue ) ,
963
+ }
964
+ }
965
+ }
934
966
935
967
impl From < i32 > for Parity {
968
+ /// Please note, this method is deprecated and will be removed in an upcoming release, it
969
+ /// is not equivalent to `from_u32()`, it is better to use `Parity::from_u32`.
936
970
fn from ( parity : i32 ) -> Parity {
937
- Parity ( parity)
971
+ if parity % 2 == 0 {
972
+ Parity :: Even
973
+ } else {
974
+ Parity :: Odd
975
+ }
938
976
}
939
977
}
940
978
941
979
impl From < Parity > for i32 {
942
980
fn from ( parity : Parity ) -> i32 {
943
- parity. 0
981
+ parity. to_i32 ( )
982
+ }
983
+ }
984
+
985
+ impl BitXor for Parity {
986
+ type Output = Parity ;
987
+
988
+ fn bitxor ( self , rhs : Parity ) -> Self :: Output {
989
+ // This works because Parity has only two values (i.e. only 1 bit of information).
990
+ if self == rhs {
991
+ Parity :: Even // 1^1==0 and 0^0==0
992
+ } else {
993
+ Parity :: Odd // 1^0==1 and 0^1==1
994
+ }
944
995
}
945
996
}
946
997
947
998
#[ cfg( feature = "serde" ) ]
948
999
#[ cfg_attr( docsrs, doc( cfg( feature = "serde" ) ) ) ]
949
1000
impl :: serde:: Serialize for Parity {
950
1001
fn serialize < S : :: serde:: Serializer > ( & self , s : S ) -> Result < S :: Ok , S :: Error > {
951
- s. serialize_i32 ( self . 0 )
1002
+ s. serialize_i32 ( self . to_i32 ( ) )
952
1003
}
953
1004
}
954
1005
@@ -969,7 +1020,7 @@ impl<'de> ::serde::Deserialize<'de> for Parity {
969
1020
fn visit_i32 < E > ( self , v : i32 ) -> Result < Self :: Value , E >
970
1021
where E : :: serde:: de:: Error
971
1022
{
972
- Ok ( Parity :: from ( v) )
1023
+ Parity :: from_i32 ( v) . map_err ( E :: custom )
973
1024
}
974
1025
}
975
1026
0 commit comments