1818#[ cfg( any( test, feature = "rand" ) ) ] use rand:: Rng ;
1919
2020use core:: { fmt, ptr, str} ;
21+ use core:: ops:: BitXor ;
2122
2223use super :: { from_hex, Secp256k1 } ;
2324use super :: Error :: { self , InvalidPublicKey , InvalidPublicKeySum , InvalidSecretKey } ;
@@ -890,7 +891,7 @@ impl XOnlyPublicKey {
890891 return Err ( Error :: InvalidPublicKey ) ;
891892 }
892893
893- Ok ( parity. into ( ) )
894+ Parity :: from_i32 ( parity)
894895 }
895896 }
896897
@@ -918,7 +919,7 @@ impl XOnlyPublicKey {
918919 let err = ffi:: secp256k1_xonly_pubkey_tweak_add_check (
919920 secp. ctx ,
920921 tweaked_ser. as_c_ptr ( ) ,
921- tweaked_parity. into ( ) ,
922+ tweaked_parity. to_i32 ( ) ,
922923 & self . 0 ,
923924 tweak. as_c_ptr ( ) ,
924925 ) ;
@@ -928,27 +929,77 @@ impl XOnlyPublicKey {
928929 }
929930}
930931
931- /// Opaque type used to hold the parity passed between FFI function calls.
932+ /// Represents the parity passed between FFI function calls.
932933#[ 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+ }
934966
935967impl 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`.
936970 fn from ( parity : i32 ) -> Parity {
937- Parity ( parity)
971+ if parity % 2 == 0 {
972+ Parity :: Even
973+ } else {
974+ Parity :: Odd
975+ }
938976 }
939977}
940978
941979impl From < Parity > for i32 {
942980 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+ }
944995 }
945996}
946997
947998#[ cfg( feature = "serde" ) ]
948999#[ cfg_attr( docsrs, doc( cfg( feature = "serde" ) ) ) ]
9491000impl :: serde:: Serialize for Parity {
9501001 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 ( ) )
9521003 }
9531004}
9541005
@@ -969,7 +1020,7 @@ impl<'de> ::serde::Deserialize<'de> for Parity {
9691020 fn visit_i32 < E > ( self , v : i32 ) -> Result < Self :: Value , E >
9701021 where E : :: serde:: de:: Error
9711022 {
972- Ok ( Parity :: from ( v) )
1023+ Parity :: from_i32 ( v) . map_err ( E :: custom )
9731024 }
9741025 }
9751026
0 commit comments