11use super :: { BigIntConversionError , ParseSignedError , Sign , Signed , utils:: twos_complement} ;
22use alloc:: string:: String ;
33use core:: str:: FromStr ;
4- use ruint:: { ToUintError , Uint , UintTryFrom } ;
4+ use ruint:: { FromUintError , ToUintError , Uint , UintTryFrom , UintTryTo } ;
55
66impl < const BITS : usize , const LIMBS : usize > TryFrom < Uint < BITS , LIMBS > > for Signed < BITS , LIMBS > {
77 type Error = BigIntConversionError ;
@@ -28,7 +28,7 @@ impl<const BITS: usize, const LIMBS: usize> TryFrom<Signed<BITS, LIMBS>> for Uin
2828 }
2929}
3030
31- /// Conversion between `Signed` of different `BITS` or `LIMBS` length.
31+ /// Conversion from `Signed` of different `BITS` or `LIMBS` length.
3232impl < const BITS : usize , const LIMBS : usize , const BITS_SRC : usize , const LIMBS_SRC : usize >
3333 UintTryFrom < Signed < BITS_SRC , LIMBS_SRC > > for Signed < BITS , LIMBS >
3434{
@@ -48,6 +48,37 @@ impl<const BITS: usize, const LIMBS: usize, const BITS_SRC: usize, const LIMBS_S
4848 }
4949}
5050
51+ /// Conversion to `Signed` of different `BITS` or `LIMBS` length.
52+ impl < const BITS : usize , const LIMBS : usize , const BITS_TARGET : usize , const LIMBS_TARGET : usize >
53+ UintTryTo < Signed < BITS_TARGET , LIMBS_TARGET > > for Signed < BITS , LIMBS >
54+ {
55+ #[ inline]
56+ fn uint_try_to (
57+ & self ,
58+ ) -> Result < Signed < BITS_TARGET , LIMBS_TARGET > , FromUintError < Signed < BITS_TARGET , LIMBS_TARGET > > >
59+ {
60+ let ( sign, abs) = self . into_sign_and_abs ( ) ;
61+ let resized = Signed :: < BITS_TARGET , LIMBS_TARGET > :: from_raw (
62+ Uint :: uint_try_to ( & abs) . map_err ( |e| match e {
63+ FromUintError :: Overflow ( b, t, v) => {
64+ FromUintError :: Overflow ( b, Signed ( t) , Signed ( v) )
65+ }
66+ } ) ?,
67+ ) ;
68+ if resized. is_negative ( ) {
69+ return Err ( FromUintError :: Overflow ( BITS_TARGET , resized, Signed :: MAX ) ) ;
70+ }
71+ Ok ( match sign {
72+ Sign :: Negative => resized. checked_neg ( ) . ok_or ( FromUintError :: Overflow (
73+ BITS_TARGET ,
74+ resized,
75+ Signed :: MAX ,
76+ ) ) ?,
77+ Sign :: Positive => resized,
78+ } )
79+ }
80+ }
81+
5182/// Conversion from positive `Signed` to `Uint` of different `BITS` or `LIMBS` length.
5283impl < const BITS : usize , const LIMBS : usize , const BITS_SRC : usize , const LIMBS_SRC : usize >
5384 UintTryFrom < Signed < BITS_SRC , LIMBS_SRC > > for Uint < BITS , LIMBS >
@@ -61,6 +92,22 @@ impl<const BITS: usize, const LIMBS: usize, const BITS_SRC: usize, const LIMBS_S
6192 }
6293}
6394
95+ /// Conversion to `Uint` from positive `Signed` of different `BITS` or `LIMBS` length.
96+ impl < const BITS : usize , const LIMBS : usize , const BITS_TARGET : usize , const LIMBS_TARGET : usize >
97+ UintTryTo < Uint < BITS_TARGET , LIMBS_TARGET > > for Signed < BITS , LIMBS >
98+ {
99+ #[ inline]
100+ fn uint_try_to (
101+ & self ,
102+ ) -> Result < Uint < BITS_TARGET , LIMBS_TARGET > , FromUintError < Uint < BITS_TARGET , LIMBS_TARGET > > >
103+ {
104+ if self . is_negative ( ) {
105+ return Err ( FromUintError :: Overflow ( BITS_TARGET , Uint :: ZERO , Uint :: MAX ) ) ;
106+ }
107+ Uint :: uint_try_to ( & self . into_raw ( ) )
108+ }
109+ }
110+
64111/// Conversion from `Uint` to positive `Signed` of different `BITS` or `LIMBS` length.
65112impl < const BITS : usize , const LIMBS : usize , const BITS_SRC : usize , const LIMBS_SRC : usize >
66113 UintTryFrom < Uint < BITS_SRC , LIMBS_SRC > > for Signed < BITS , LIMBS >
@@ -76,6 +123,29 @@ impl<const BITS: usize, const LIMBS: usize, const BITS_SRC: usize, const LIMBS_S
76123 }
77124}
78125
126+ /// Conversion to positive `Signed` from `Uint` of different `BITS` or `LIMBS` length.
127+ impl < const BITS : usize , const LIMBS : usize , const BITS_TARGET : usize , const LIMBS_TARGET : usize >
128+ UintTryTo < Signed < BITS_TARGET , LIMBS_TARGET > > for Uint < BITS , LIMBS >
129+ {
130+ #[ inline]
131+ fn uint_try_to (
132+ & self ,
133+ ) -> Result < Signed < BITS_TARGET , LIMBS_TARGET > , FromUintError < Signed < BITS_TARGET , LIMBS_TARGET > > >
134+ {
135+ let resized = Signed :: < BITS_TARGET , LIMBS_TARGET > :: from_raw (
136+ Self :: uint_try_to ( self ) . map_err ( |e| match e {
137+ FromUintError :: Overflow ( b, t, v) => {
138+ FromUintError :: Overflow ( b, Signed ( t) , Signed ( v) )
139+ }
140+ } ) ?,
141+ ) ;
142+ if resized. is_negative ( ) {
143+ return Err ( FromUintError :: Overflow ( BITS_TARGET , resized, Signed :: MAX ) ) ;
144+ }
145+ Ok ( resized)
146+ }
147+ }
148+
79149fn signed_err < const BITS : usize , const LIMBS : usize > (
80150 err : ToUintError < Uint < BITS , LIMBS > > ,
81151) -> ToUintError < Signed < BITS , LIMBS > > {
0 commit comments