@@ -210,6 +210,9 @@ impl std::hash::Hash for CqlTimeuuid {
210210/// The library support (e.g. conversion from [`CqlValue`]) for these types is
211211/// enabled via `num-bigint-03` and `num-bigint-04` crate features.
212212///
213+ /// This struct holds owned bytes. If you wish to borrow the bytes instead,
214+ /// see [`CqlVarintBorrowed`] documentation.
215+ ///
213216/// # DB data format
214217/// Notice that [constructors](CqlVarint#impl-CqlVarint)
215218/// don't perform any normalization on the provided data.
@@ -223,6 +226,13 @@ impl std::hash::Hash for CqlTimeuuid {
223226#[ derive( Clone , Eq , Debug ) ]
224227pub struct CqlVarint ( Vec < u8 > ) ;
225228
229+ /// A borrowed version of native CQL `varint` representation.
230+ ///
231+ /// Refer to the documentation of [`CqlVarint`].
232+ /// Especially, see the disclaimer about [non-normalized values](CqlVarint#db-data-format).
233+ #[ derive( Clone , Eq , Debug ) ]
234+ pub struct CqlVarintBorrowed < ' b > ( & ' b [ u8 ] ) ;
235+
226236/// Constructors from bytes
227237impl CqlVarint {
228238 /// Creates a [`CqlVarint`] from an array of bytes in
@@ -242,6 +252,17 @@ impl CqlVarint {
242252 }
243253}
244254
255+ /// Constructors from bytes
256+ impl < ' b > CqlVarintBorrowed < ' b > {
257+ /// Creates a [`CqlVarintBorrowed`] from a slice of bytes in
258+ /// two's complement binary big-endian representation.
259+ ///
260+ /// See: disclaimer about [non-normalized values](CqlVarint#db-data-format).
261+ pub fn from_signed_bytes_be_slice ( digits : & ' b [ u8 ] ) -> Self {
262+ Self ( digits)
263+ }
264+ }
265+
245266/// Conversion to bytes
246267impl CqlVarint {
247268 /// Converts [`CqlVarint`] to an array of bytes in two's
@@ -257,9 +278,39 @@ impl CqlVarint {
257278 }
258279}
259280
260- impl CqlVarint {
281+ /// Conversion to bytes
282+ impl CqlVarintBorrowed < ' _ > {
283+ /// Returns a slice of bytes in two's complement
284+ /// binary big-endian representation.
285+ pub fn as_signed_bytes_be_slice ( & self ) -> & [ u8 ] {
286+ self . 0
287+ }
288+ }
289+
290+ /// An internal utility trait used to implement [`AsNormalizedVarintSlice`]
291+ /// for both [`CqlVarint`] and [`CqlVarintBorrowed`].
292+ trait AsVarintSlice {
293+ fn as_slice ( & self ) -> & [ u8 ] ;
294+ }
295+ impl AsVarintSlice for CqlVarint {
296+ fn as_slice ( & self ) -> & [ u8 ] {
297+ self . as_signed_bytes_be_slice ( )
298+ }
299+ }
300+ impl AsVarintSlice for CqlVarintBorrowed < ' _ > {
301+ fn as_slice ( & self ) -> & [ u8 ] {
302+ self . as_signed_bytes_be_slice ( )
303+ }
304+ }
305+
306+ /// An internal utility trait used to implement [`PartialEq`] and [`std::hash::Hash`]
307+ /// for [`CqlVarint`] and [`CqlVarintBorrowed`].
308+ trait AsNormalizedVarintSlice {
309+ fn as_normalized_slice ( & self ) -> & [ u8 ] ;
310+ }
311+ impl < V : AsVarintSlice > AsNormalizedVarintSlice for V {
261312 fn as_normalized_slice ( & self ) -> & [ u8 ] {
262- let digits = self . 0 . as_slice ( ) ;
313+ let digits = self . as_slice ( ) ;
263314 if digits. is_empty ( ) {
264315 // num-bigint crate normalizes empty vector to 0.
265316 // We will follow the same approach.
@@ -293,6 +344,58 @@ impl CqlVarint {
293344 }
294345}
295346
347+ /// Compares two [`CqlVarint`] values after normalization.
348+ ///
349+ /// # Example
350+ ///
351+ /// ```rust
352+ /// # use scylla_cql::frame::value::CqlVarint;
353+ /// let non_normalized_bytes = vec![0x00, 0x01];
354+ /// let normalized_bytes = vec![0x01];
355+ /// assert_eq!(
356+ /// CqlVarint::from_signed_bytes_be(non_normalized_bytes),
357+ /// CqlVarint::from_signed_bytes_be(normalized_bytes)
358+ /// );
359+ /// ```
360+ impl PartialEq for CqlVarint {
361+ fn eq ( & self , other : & Self ) -> bool {
362+ self . as_normalized_slice ( ) == other. as_normalized_slice ( )
363+ }
364+ }
365+
366+ /// Computes the hash of normalized [`CqlVarint`].
367+ impl std:: hash:: Hash for CqlVarint {
368+ fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
369+ self . as_normalized_slice ( ) . hash ( state)
370+ }
371+ }
372+
373+ /// Compares two [`CqlVarintBorrowed`] values after normalization.
374+ ///
375+ /// # Example
376+ ///
377+ /// ```rust
378+ /// # use scylla_cql::frame::value::CqlVarintBorrowed;
379+ /// let non_normalized_bytes = &[0x00, 0x01];
380+ /// let normalized_bytes = &[0x01];
381+ /// assert_eq!(
382+ /// CqlVarintBorrowed::from_signed_bytes_be_slice(non_normalized_bytes),
383+ /// CqlVarintBorrowed::from_signed_bytes_be_slice(normalized_bytes)
384+ /// );
385+ /// ```
386+ impl PartialEq for CqlVarintBorrowed < ' _ > {
387+ fn eq ( & self , other : & Self ) -> bool {
388+ self . as_normalized_slice ( ) == other. as_normalized_slice ( )
389+ }
390+ }
391+
392+ /// Computes the hash of normalized [`CqlVarintBorrowed`].
393+ impl std:: hash:: Hash for CqlVarintBorrowed < ' _ > {
394+ fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
395+ self . as_normalized_slice ( ) . hash ( state)
396+ }
397+ }
398+
296399#[ cfg( feature = "num-bigint-03" ) ]
297400impl From < num_bigint_03:: BigInt > for CqlVarint {
298401 fn from ( value : num_bigint_03:: BigInt ) -> Self {
@@ -307,6 +410,13 @@ impl From<CqlVarint> for num_bigint_03::BigInt {
307410 }
308411}
309412
413+ #[ cfg( feature = "num-bigint-03" ) ]
414+ impl From < CqlVarintBorrowed < ' _ > > for num_bigint_03:: BigInt {
415+ fn from ( val : CqlVarintBorrowed < ' _ > ) -> Self {
416+ num_bigint_03:: BigInt :: from_signed_bytes_be ( val. 0 )
417+ }
418+ }
419+
310420#[ cfg( feature = "num-bigint-04" ) ]
311421impl From < num_bigint_04:: BigInt > for CqlVarint {
312422 fn from ( value : num_bigint_04:: BigInt ) -> Self {
@@ -321,29 +431,10 @@ impl From<CqlVarint> for num_bigint_04::BigInt {
321431 }
322432}
323433
324- /// Compares two [`CqlVarint`] values after normalization.
325- ///
326- /// # Example
327- ///
328- /// ```rust
329- /// # use scylla_cql::frame::value::CqlVarint;
330- /// let non_normalized_bytes = vec![0x00, 0x01];
331- /// let normalized_bytes = vec![0x01];
332- /// assert_eq!(
333- /// CqlVarint::from_signed_bytes_be(non_normalized_bytes),
334- /// CqlVarint::from_signed_bytes_be(normalized_bytes)
335- /// );
336- /// ```
337- impl PartialEq for CqlVarint {
338- fn eq ( & self , other : & Self ) -> bool {
339- self . as_normalized_slice ( ) == other. as_normalized_slice ( )
340- }
341- }
342-
343- /// Computes the hash of normalized [`CqlVarint`].
344- impl std:: hash:: Hash for CqlVarint {
345- fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
346- self . as_normalized_slice ( ) . hash ( state)
434+ #[ cfg( feature = "num-bigint-04" ) ]
435+ impl From < CqlVarintBorrowed < ' _ > > for num_bigint_04:: BigInt {
436+ fn from ( val : CqlVarintBorrowed < ' _ > ) -> Self {
437+ num_bigint_04:: BigInt :: from_signed_bytes_be ( val. 0 )
347438 }
348439}
349440
@@ -353,6 +444,9 @@ impl std::hash::Hash for CqlVarint {
353444/// - a [`CqlVarint`] value
354445/// - 32-bit integer which determines the position of the decimal point
355446///
447+ /// This struct holds owned bytes. If you wish to borrow the bytes instead,
448+ /// see [`CqlDecimalBorrowed`] documentation.
449+ ///
356450/// The type is not very useful in most use cases.
357451/// However, users can make use of more complex types
358452/// such as `bigdecimal::BigDecimal` (v0.4).
@@ -369,6 +463,20 @@ pub struct CqlDecimal {
369463 scale : i32 ,
370464}
371465
466+ /// Borrowed version of native CQL `decimal` representation.
467+ ///
468+ /// Represented as a pair:
469+ /// - a [`CqlVarintBorrowed`] value
470+ /// - 32-bit integer which determines the position of the decimal point
471+ ///
472+ /// Refer to the documentation of [`CqlDecimal`].
473+ /// Especially, see the disclaimer about [non-normalized values](CqlDecimal#db-data-format).
474+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
475+ pub struct CqlDecimalBorrowed < ' b > {
476+ int_val : CqlVarintBorrowed < ' b > ,
477+ scale : i32 ,
478+ }
479+
372480/// Constructors
373481impl CqlDecimal {
374482 /// Creates a [`CqlDecimal`] from an array of bytes
@@ -391,6 +499,20 @@ impl CqlDecimal {
391499 }
392500}
393501
502+ /// Constructors
503+ impl < ' b > CqlDecimalBorrowed < ' b > {
504+ /// Creates a [`CqlDecimalBorrowed`] from a slice of bytes
505+ /// representing [`CqlVarintBorrowed`] and a 32-bit scale.
506+ ///
507+ /// See: disclaimer about [non-normalized values](CqlVarint#db-data-format).
508+ pub fn from_signed_be_bytes_slice_and_exponent ( bytes : & ' b [ u8 ] , scale : i32 ) -> Self {
509+ Self {
510+ int_val : CqlVarintBorrowed :: from_signed_bytes_be_slice ( bytes) ,
511+ scale,
512+ }
513+ }
514+ }
515+
394516/// Conversion to raw bytes
395517impl CqlDecimal {
396518 /// Returns a slice of bytes in two's complement
@@ -406,6 +528,15 @@ impl CqlDecimal {
406528 }
407529}
408530
531+ /// Conversion to raw bytes
532+ impl CqlDecimalBorrowed < ' _ > {
533+ /// Returns a slice of bytes in two's complement
534+ /// binary big-endian representation and a scale.
535+ pub fn as_signed_be_bytes_slice_and_exponent ( & self ) -> ( & [ u8 ] , i32 ) {
536+ ( self . int_val . as_signed_bytes_be_slice ( ) , self . scale )
537+ }
538+ }
539+
409540#[ cfg( feature = "bigdecimal-04" ) ]
410541impl From < CqlDecimal > for bigdecimal_04:: BigDecimal {
411542 fn from ( value : CqlDecimal ) -> Self {
@@ -418,6 +549,18 @@ impl From<CqlDecimal> for bigdecimal_04::BigDecimal {
418549 }
419550}
420551
552+ #[ cfg( feature = "bigdecimal-04" ) ]
553+ impl From < CqlDecimalBorrowed < ' _ > > for bigdecimal_04:: BigDecimal {
554+ fn from ( value : CqlDecimalBorrowed ) -> Self {
555+ Self :: from ( (
556+ bigdecimal_04:: num_bigint:: BigInt :: from_signed_bytes_be (
557+ value. int_val . as_signed_bytes_be_slice ( ) ,
558+ ) ,
559+ value. scale as i64 ,
560+ ) )
561+ }
562+ }
563+
421564#[ cfg( feature = "bigdecimal-04" ) ]
422565impl TryFrom < bigdecimal_04:: BigDecimal > for CqlDecimal {
423566 type Error = <i64 as TryInto < i32 > >:: Error ;
0 commit comments