@@ -220,6 +220,9 @@ impl std::hash::Hash for CqlTimeuuid {
220220/// The library support (e.g. conversion from [`CqlValue`]) for these types is
221221/// enabled via `num-bigint-03` and `num-bigint-04` crate features.
222222///
223+ /// This struct holds owned bytes. If you wish to borrow the bytes instead,
224+ /// see [`CqlVarintBorrowed`] documentation.
225+ ///
223226/// # DB data format
224227/// Notice that [constructors](CqlVarint#impl-CqlVarint)
225228/// don't perform any normalization on the provided data.
@@ -233,6 +236,13 @@ impl std::hash::Hash for CqlTimeuuid {
233236#[ derive( Clone , Eq , Debug ) ]
234237pub struct CqlVarint ( Vec < u8 > ) ;
235238
239+ /// A borrowed version of native CQL `varint` representation.
240+ ///
241+ /// Refer to the documentation of [`CqlVarint`].
242+ /// Especially, see the disclaimer about [non-normalized values](CqlVarint#db-data-format).
243+ #[ derive( Clone , Eq , Debug ) ]
244+ pub struct CqlVarintBorrowed < ' b > ( & ' b [ u8 ] ) ;
245+
236246/// Constructors from bytes
237247impl CqlVarint {
238248 /// Creates a [`CqlVarint`] from an array of bytes in
@@ -252,6 +262,17 @@ impl CqlVarint {
252262 }
253263}
254264
265+ /// Constructors from bytes
266+ impl < ' b > CqlVarintBorrowed < ' b > {
267+ /// Creates a [`CqlVarintBorrowed`] from a slice of bytes in
268+ /// two's complement binary big-endian representation.
269+ ///
270+ /// See: disclaimer about [non-normalized values](CqlVarint#db-data-format).
271+ pub fn from_signed_bytes_be_slice ( digits : & ' b [ u8 ] ) -> Self {
272+ Self ( digits)
273+ }
274+ }
275+
255276/// Conversion to bytes
256277impl CqlVarint {
257278 /// Converts [`CqlVarint`] to an array of bytes in two's
@@ -267,9 +288,39 @@ impl CqlVarint {
267288 }
268289}
269290
270- impl CqlVarint {
291+ /// Conversion to bytes
292+ impl CqlVarintBorrowed < ' _ > {
293+ /// Returns a slice of bytes in two's complement
294+ /// binary big-endian representation.
295+ pub fn as_signed_bytes_be_slice ( & self ) -> & [ u8 ] {
296+ self . 0
297+ }
298+ }
299+
300+ /// An internal utility trait used to implement [`AsNormalizedVarintSlice`]
301+ /// for both [`CqlVarint`] and [`CqlVarintBorrowed`].
302+ trait AsVarintSlice {
303+ fn as_slice ( & self ) -> & [ u8 ] ;
304+ }
305+ impl AsVarintSlice for CqlVarint {
306+ fn as_slice ( & self ) -> & [ u8 ] {
307+ self . as_signed_bytes_be_slice ( )
308+ }
309+ }
310+ impl AsVarintSlice for CqlVarintBorrowed < ' _ > {
311+ fn as_slice ( & self ) -> & [ u8 ] {
312+ self . as_signed_bytes_be_slice ( )
313+ }
314+ }
315+
316+ /// An internal utility trait used to implement [`PartialEq`] and [`std::hash::Hash`]
317+ /// for [`CqlVarint`] and [`CqlVarintBorrowed`].
318+ trait AsNormalizedVarintSlice {
319+ fn as_normalized_slice ( & self ) -> & [ u8 ] ;
320+ }
321+ impl < V : AsVarintSlice > AsNormalizedVarintSlice for V {
271322 fn as_normalized_slice ( & self ) -> & [ u8 ] {
272- let digits = self . 0 . as_slice ( ) ;
323+ let digits = self . as_slice ( ) ;
273324 if digits. is_empty ( ) {
274325 // num-bigint crate normalizes empty vector to 0.
275326 // We will follow the same approach.
@@ -329,6 +380,32 @@ impl std::hash::Hash for CqlVarint {
329380 }
330381}
331382
383+ /// Compares two [`CqlVarintBorrowed`] values after normalization.
384+ ///
385+ /// # Example
386+ ///
387+ /// ```rust
388+ /// # use scylla_cql::frame::value::CqlVarintBorrowed;
389+ /// let non_normalized_bytes = &[0x00, 0x01];
390+ /// let normalized_bytes = &[0x01];
391+ /// assert_eq!(
392+ /// CqlVarintBorrowed::from_signed_bytes_be_slice(non_normalized_bytes),
393+ /// CqlVarintBorrowed::from_signed_bytes_be_slice(normalized_bytes)
394+ /// );
395+ /// ```
396+ impl PartialEq for CqlVarintBorrowed < ' _ > {
397+ fn eq ( & self , other : & Self ) -> bool {
398+ self . as_normalized_slice ( ) == other. as_normalized_slice ( )
399+ }
400+ }
401+
402+ /// Computes the hash of normalized [`CqlVarintBorrowed`].
403+ impl std:: hash:: Hash for CqlVarintBorrowed < ' _ > {
404+ fn hash < H : std:: hash:: Hasher > ( & self , state : & mut H ) {
405+ self . as_normalized_slice ( ) . hash ( state)
406+ }
407+ }
408+
332409#[ cfg( feature = "num-bigint-03" ) ]
333410impl From < num_bigint_03:: BigInt > for CqlVarint {
334411 fn from ( value : num_bigint_03:: BigInt ) -> Self {
@@ -343,6 +420,13 @@ impl From<CqlVarint> for num_bigint_03::BigInt {
343420 }
344421}
345422
423+ #[ cfg( feature = "num-bigint-03" ) ]
424+ impl From < CqlVarintBorrowed < ' _ > > for num_bigint_03:: BigInt {
425+ fn from ( val : CqlVarintBorrowed < ' _ > ) -> Self {
426+ num_bigint_03:: BigInt :: from_signed_bytes_be ( val. 0 )
427+ }
428+ }
429+
346430#[ cfg( feature = "num-bigint-04" ) ]
347431impl From < num_bigint_04:: BigInt > for CqlVarint {
348432 fn from ( value : num_bigint_04:: BigInt ) -> Self {
@@ -357,6 +441,13 @@ impl From<CqlVarint> for num_bigint_04::BigInt {
357441 }
358442}
359443
444+ #[ cfg( feature = "num-bigint-04" ) ]
445+ impl From < CqlVarintBorrowed < ' _ > > for num_bigint_04:: BigInt {
446+ fn from ( val : CqlVarintBorrowed < ' _ > ) -> Self {
447+ num_bigint_04:: BigInt :: from_signed_bytes_be ( val. 0 )
448+ }
449+ }
450+
360451/// Native CQL `decimal` representation.
361452///
362453/// Represented as a pair:
0 commit comments