• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16943034431

13 Aug 2025 04:15PM UTC coverage: 87.687% (+0.02%) from 87.665%
16943034431

Pull #4230

github

web-flow
Merge 655f3955a into e305f7ca3
Pull Request #4230: feat[expr]: add back the expression folder, implemented over `Node`

111 of 125 new or added lines in 2 files covered. (88.8%)

1 existing line in 1 file now uncovered.

56608 of 64557 relevant lines covered (87.69%)

626279.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.3
/vortex-scalar/src/lib.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
//! Scalar values and types for the Vortex system.
5
//!
6
//! This crate provides scalar types and values that can be used to represent individual
7
//! data elements in the Vortex array system. Scalars are composed of a logical data type
8
//! ([`DType`]) and a value ([`ScalarValue`]).
9

10
#![deny(missing_docs)]
11

12
use std::cmp::Ordering;
13
use std::hash::Hash;
14
use std::sync::Arc;
15

16
pub use scalar_type::ScalarType;
17
use vortex_buffer::{Buffer, BufferString, ByteBuffer};
18
use vortex_dtype::half::f16;
19
use vortex_dtype::{DECIMAL128_MAX_PRECISION, DType, Nullability};
20
#[cfg(feature = "arbitrary")]
21
pub mod arbitrary;
22
mod arrow;
23
mod bigint;
24
mod binary;
25
mod bool;
26
mod decimal;
27
mod display;
28
mod extension;
29
mod list;
30
mod null;
31
mod primitive;
32
mod proto;
33
mod pvalue;
34
mod scalar_type;
35
mod scalar_value;
36
mod struct_;
37
#[cfg(test)]
38
mod tests;
39
mod utf8;
40

41
pub use bigint::*;
42
pub use binary::*;
43
pub use bool::*;
44
pub use decimal::*;
45
pub use extension::*;
46
pub use list::*;
47
pub use primitive::*;
48
pub use pvalue::*;
49
pub use scalar_value::*;
50
pub use struct_::*;
51
pub use utf8::*;
52
use vortex_error::{VortexExpect, VortexResult, vortex_bail};
53

54
/// A single logical item, composed of both a [`ScalarValue`] and a logical [`DType`].
55
///
56
/// A [`ScalarValue`] is opaque, and should be accessed via one of the type-specific scalar wrappers
57
/// for example [`BoolScalar`], [`PrimitiveScalar`], etc.
58
///
59
/// Note that [`PartialOrd`] is implemented only for an exact match of the scalar's dtype,
60
/// including nullability. When the DType does match, ordering is nulls first (lowest), then the
61
/// natural ordering of the scalar value.
62
#[derive(Debug, Clone)]
63
pub struct Scalar {
64
    dtype: DType,
65
    value: ScalarValue,
66
}
67

68
impl Scalar {
69
    /// Creates a new scalar with the given data type and value.
70
    pub fn new(dtype: DType, value: ScalarValue) -> Self {
102,145,972✔
71
        Self { dtype, value }
102,145,972✔
72
    }
102,145,972✔
73

74
    /// Returns a reference to the scalar's data type.
75
    #[inline]
76
    pub fn dtype(&self) -> &DType {
256,077,956✔
77
        &self.dtype
256,077,956✔
78
    }
256,077,956✔
79

80
    /// Returns a reference to the scalar's underlying value.
81
    #[inline]
82
    pub fn value(&self) -> &ScalarValue {
67,401,945✔
83
        &self.value
67,401,945✔
84
    }
67,401,945✔
85

86
    /// Consumes the scalar and returns its data type and value as a tuple.
87
    #[inline]
88
    pub fn into_parts(self) -> (DType, ScalarValue) {
1✔
89
        (self.dtype, self.value)
1✔
90
    }
1✔
91

92
    /// Consumes the scalar and returns its underlying value.
93
    #[inline]
94
    pub fn into_value(self) -> ScalarValue {
606,586✔
95
        self.value
606,586✔
96
    }
606,586✔
97

98
    /// Returns true if the scalar is not null.
99
    pub fn is_valid(&self) -> bool {
1,177,340✔
100
        !self.value.is_null()
1,177,340✔
101
    }
1,177,340✔
102

103
    /// Returns true if the scalar is null.
104
    pub fn is_null(&self) -> bool {
14,888,564✔
105
        self.value.is_null()
14,888,564✔
106
    }
14,888,564✔
107

108
    /// Creates a null scalar with the given nullable data type.
109
    ///
110
    /// # Panics
111
    ///
112
    /// Panics if the data type is not nullable.
113
    pub fn null(dtype: DType) -> Self {
8,210,954✔
114
        assert!(
8,210,954✔
115
            dtype.is_nullable(),
8,210,954✔
116
            "Creating null scalar for non-nullable DType {dtype}"
×
117
        );
118
        Self {
8,210,954✔
119
            dtype,
8,210,954✔
120
            value: ScalarValue(InnerScalarValue::Null),
8,210,954✔
121
        }
8,210,954✔
122
    }
8,210,954✔
123

124
    /// Creates a null scalar for the given scalar type.
125
    ///
126
    /// The resulting scalar will have a nullable version of the type's data type.
127
    pub fn null_typed<T: ScalarType>() -> Self {
59✔
128
        Self {
59✔
129
            dtype: T::dtype().as_nullable(),
59✔
130
            value: ScalarValue(InnerScalarValue::Null),
59✔
131
        }
59✔
132
    }
59✔
133

134
    /// Casts the scalar to the target data type.
135
    ///
136
    /// Returns an error if the cast is not supported or if the value cannot be represented
137
    /// in the target type.
138
    pub fn cast(&self, target: &DType) -> VortexResult<Self> {
9,560,673✔
139
        if let DType::Extension(ext_dtype) = target {
9,560,673✔
140
            let storage_scalar = self.cast_to_non_extension(ext_dtype.storage_dtype())?;
1,504✔
141
            Ok(Scalar::extension(ext_dtype.clone(), storage_scalar))
1,503✔
142
        } else {
143
            self.cast_to_non_extension(target)
9,559,169✔
144
        }
145
    }
9,560,673✔
146

147
    fn cast_to_non_extension(&self, target: &DType) -> VortexResult<Self> {
9,560,673✔
148
        assert!(!matches!(target, DType::Extension(..)));
9,560,673✔
149
        if self.is_null() {
9,560,673✔
150
            if target.is_nullable() {
3,618✔
151
                return Ok(Scalar::new(target.clone(), self.value.clone()));
3,383✔
152
            } else {
153
                vortex_bail!(
235✔
154
                    "Cannot cast null to {}: target type is non-nullable",
235✔
155
                    target
156
                )
157
            }
158
        }
9,557,055✔
159

160
        if self.dtype().eq_ignore_nullability(target) {
9,557,055✔
161
            return Ok(Scalar::new(target.clone(), self.value.clone()));
9,511,380✔
162
        }
45,675✔
163

164
        match &self.dtype {
45,675✔
165
            DType::Null => unreachable!(), // handled by if is_null case
×
166
            DType::Bool(_) => self.as_bool().cast(target),
195✔
167
            DType::Primitive(..) => self.as_primitive().cast(target),
43,855✔
168
            DType::Decimal(..) => self.as_decimal().cast(target),
49✔
169
            DType::Utf8(_) => self.as_utf8().cast(target),
78✔
170
            DType::Binary(_) => self.as_binary().cast(target),
×
171
            DType::Struct(..) => self.as_struct().cast(target),
×
172
            DType::List(..) => self.as_list().cast(target),
6✔
173
            DType::Extension(..) => self.as_extension().cast(target),
1,492✔
174
        }
175
    }
9,560,673✔
176

177
    /// Converts the scalar to have a nullable version of its data type.
178
    pub fn into_nullable(self) -> Self {
4,155,622✔
179
        Self {
4,155,622✔
180
            dtype: self.dtype.as_nullable(),
4,155,622✔
181
            value: self.value,
4,155,622✔
182
        }
4,155,622✔
183
    }
4,155,622✔
184

185
    /// Returns the size of the scalar in bytes, uncompressed.
186
    pub fn nbytes(&self) -> usize {
36✔
187
        match self.dtype() {
36✔
188
            DType::Null => 0,
1✔
189
            DType::Bool(_) => 1,
1✔
190
            DType::Primitive(ptype, _) => ptype.byte_width(),
17✔
191
            DType::Decimal(dt, _) => {
7✔
192
                if dt.precision() <= DECIMAL128_MAX_PRECISION {
7✔
193
                    size_of::<i128>()
4✔
194
                } else {
195
                    size_of::<i256>()
3✔
196
                }
197
            }
198
            DType::Binary(_) | DType::Utf8(_) => self
5✔
199
                .value()
5✔
200
                .as_buffer()
5✔
201
                .ok()
5✔
202
                .flatten()
5✔
203
                .map_or(0, |s| s.len()),
5✔
204
            DType::Struct(_dtype, _) => self
2✔
205
                .as_struct()
2✔
206
                .fields()
2✔
207
                .map(|fields| fields.into_iter().map(|f| f.nbytes()).sum::<usize>())
4✔
208
                .unwrap_or_default(),
2✔
209
            DType::List(_dtype, _) => self
2✔
210
                .as_list()
2✔
211
                .elements()
2✔
212
                .map(|fields| fields.into_iter().map(|f| f.nbytes()).sum::<usize>())
6✔
213
                .unwrap_or_default(),
2✔
214
            DType::Extension(_ext_dtype) => self.as_extension().storage().nbytes(),
1✔
215
        }
216
    }
36✔
217

218
    /// Creates a "default" scalar value for the given data type.
219
    ///
220
    /// For nullable types, returns null. For non-nullable types, returns
221
    /// an appropriate zero/empty value.
222
    pub fn default_value(dtype: DType) -> Self {
3,787✔
223
        if dtype.is_nullable() {
3,787✔
224
            return Self::null(dtype);
118✔
225
        }
3,669✔
226

227
        match dtype {
3,669✔
228
            DType::Null => Self::null(dtype),
×
229
            DType::Bool(nullability) => Self::bool(false, nullability),
×
230
            DType::Primitive(pt, nullability) => {
3,667✔
231
                Self::primitive_value(PValue::zero(pt), pt, nullability)
3,667✔
232
            }
233
            DType::Decimal(dt, nullability) => {
×
234
                Self::decimal(DecimalValue::from(0), dt, nullability)
×
235
            }
236
            DType::Utf8(nullability) => Self::utf8("", nullability),
×
237
            DType::Binary(nullability) => Self::binary(Buffer::empty(), nullability),
×
238
            DType::Struct(sf, nullability) => {
1✔
239
                let fields: Vec<_> = sf.fields().map(Scalar::default_value).collect();
1✔
240
                Self::struct_(DType::Struct(sf, nullability), fields)
1✔
241
            }
242
            DType::List(dt, nullability) => Self::list(dt, vec![], nullability),
1✔
243
            DType::Extension(dt) => {
×
244
                let scalar = Self::default_value(dt.storage_dtype().clone());
×
245
                Self::extension(dt, scalar)
×
246
            }
247
        }
248
    }
3,787✔
249
}
250

251
impl Scalar {
252
    /// Returns a view of the scalar as a boolean scalar.
253
    ///
254
    /// # Panics
255
    ///
256
    /// Panics if the scalar is not a boolean type.
257
    pub fn as_bool(&self) -> BoolScalar<'_> {
38,590,403✔
258
        BoolScalar::try_from(self).vortex_expect("Failed to convert scalar to bool")
38,590,403✔
259
    }
38,590,403✔
260

261
    /// Returns a view of the scalar as a boolean scalar if it has a boolean type.
262
    pub fn as_bool_opt(&self) -> Option<BoolScalar<'_>> {
4,065✔
263
        matches!(self.dtype, DType::Bool(..)).then(|| self.as_bool())
4,065✔
264
    }
4,065✔
265

266
    /// Returns a view of the scalar as a primitive scalar.
267
    ///
268
    /// # Panics
269
    ///
270
    /// Panics if the scalar is not a primitive type.
271
    pub fn as_primitive(&self) -> PrimitiveScalar<'_> {
56,365,298✔
272
        PrimitiveScalar::try_from(self).vortex_expect("Failed to convert scalar to primitive")
56,365,298✔
273
    }
56,365,298✔
274

275
    /// Returns a view of the scalar as a primitive scalar if it has a primitive type.
276
    pub fn as_primitive_opt(&self) -> Option<PrimitiveScalar<'_>> {
1,835✔
277
        matches!(self.dtype, DType::Primitive(..)).then(|| self.as_primitive())
1,835✔
278
    }
1,835✔
279

280
    /// Returns a view of the scalar as a decimal scalar.
281
    ///
282
    /// # Panics
283
    ///
284
    /// Panics if the scalar is not a decimal type.
285
    pub fn as_decimal(&self) -> DecimalScalar<'_> {
1,536,279✔
286
        DecimalScalar::try_from(self).vortex_expect("Failed to convert scalar to decimal")
1,536,279✔
287
    }
1,536,279✔
288

289
    /// Returns a view of the scalar as a decimal scalar if it has a decimal type.
290
    pub fn as_decimal_opt(&self) -> Option<DecimalScalar<'_>> {
×
291
        matches!(self.dtype, DType::Decimal(..)).then(|| self.as_decimal())
×
292
    }
×
293

294
    /// Returns a view of the scalar as a UTF-8 string scalar.
295
    ///
296
    /// # Panics
297
    ///
298
    /// Panics if the scalar is not a UTF-8 type.
299
    pub fn as_utf8(&self) -> Utf8Scalar<'_> {
1,267,015✔
300
        Utf8Scalar::try_from(self).vortex_expect("Failed to convert scalar to utf8")
1,267,015✔
301
    }
1,267,015✔
302

303
    /// Returns a view of the scalar as a UTF-8 string scalar if it has a UTF-8 type.
304
    pub fn as_utf8_opt(&self) -> Option<Utf8Scalar<'_>> {
×
305
        matches!(self.dtype, DType::Utf8(..)).then(|| self.as_utf8())
×
306
    }
×
307

308
    /// Returns a view of the scalar as a binary scalar.
309
    ///
310
    /// # Panics
311
    ///
312
    /// Panics if the scalar is not a binary type.
313
    pub fn as_binary(&self) -> BinaryScalar<'_> {
513,903✔
314
        BinaryScalar::try_from(self).vortex_expect("Failed to convert scalar to binary")
513,903✔
315
    }
513,903✔
316

317
    /// Returns a view of the scalar as a binary scalar if it has a binary type.
318
    pub fn as_binary_opt(&self) -> Option<BinaryScalar<'_>> {
7✔
319
        matches!(self.dtype, DType::Binary(..)).then(|| self.as_binary())
7✔
320
    }
7✔
321

322
    /// Returns a view of the scalar as a struct scalar.
323
    ///
324
    /// # Panics
325
    ///
326
    /// Panics if the scalar is not a struct type.
327
    pub fn as_struct(&self) -> StructScalar<'_> {
425,367✔
328
        StructScalar::try_from(self).vortex_expect("Failed to convert scalar to struct")
425,367✔
329
    }
425,367✔
330

331
    /// Returns a view of the scalar as a struct scalar if it has a struct type.
332
    pub fn as_struct_opt(&self) -> Option<StructScalar<'_>> {
×
333
        matches!(self.dtype, DType::Struct(..)).then(|| self.as_struct())
×
334
    }
×
335

336
    /// Returns a view of the scalar as a list scalar.
337
    ///
338
    /// # Panics
339
    ///
340
    /// Panics if the scalar is not a list type.
341
    pub fn as_list(&self) -> ListScalar<'_> {
109,749✔
342
        ListScalar::try_from(self).vortex_expect("Failed to convert scalar to list")
109,749✔
343
    }
109,749✔
344

345
    /// Returns a view of the scalar as a list scalar if it has a list type.
346
    pub fn as_list_opt(&self) -> Option<ListScalar<'_>> {
195✔
347
        matches!(self.dtype, DType::List(..)).then(|| self.as_list())
195✔
348
    }
195✔
349

350
    /// Returns a view of the scalar as an extension scalar.
351
    ///
352
    /// # Panics
353
    ///
354
    /// Panics if the scalar is not an extension type.
355
    pub fn as_extension(&self) -> ExtScalar<'_> {
748,564✔
356
        ExtScalar::try_from(self).vortex_expect("Failed to convert scalar to extension")
748,564✔
357
    }
748,564✔
358

359
    /// Returns a view of the scalar as an extension scalar if it has an extension type.
360
    pub fn as_extension_opt(&self) -> Option<ExtScalar<'_>> {
×
361
        matches!(self.dtype, DType::Extension(..)).then(|| self.as_extension())
×
362
    }
×
363
}
364

365
impl PartialEq for Scalar {
366
    fn eq(&self, other: &Self) -> bool {
28,104,675✔
367
        if !self.dtype.eq_ignore_nullability(&other.dtype) {
28,104,675✔
UNCOV
368
            return false;
×
369
        }
28,104,675✔
370

371
        match self.dtype() {
28,104,675✔
372
            DType::Null => true,
235,795✔
373
            DType::Bool(_) => self.as_bool() == other.as_bool(),
12,668,782✔
374
            DType::Primitive(..) => self.as_primitive() == other.as_primitive(),
13,347,580✔
375
            DType::Decimal(..) => self.as_decimal() == other.as_decimal(),
760,793✔
376
            DType::Utf8(_) => self.as_utf8() == other.as_utf8(),
613,637✔
377
            DType::Binary(_) => self.as_binary() == other.as_binary(),
8,232✔
378
            DType::Struct(..) => self.as_struct() == other.as_struct(),
51,599✔
379
            DType::List(..) => self.as_list() == other.as_list(),
51,617✔
380
            DType::Extension(_) => self.as_extension() == other.as_extension(),
366,640✔
381
        }
382
    }
28,104,675✔
383
}
384

385
impl Eq for Scalar {}
386

387
impl PartialOrd for Scalar {
388
    /// Compares two scalar values for ordering.
389
    ///
390
    /// # Returns
391
    /// - `Some(Ordering)` if both scalars have the same data type (ignoring nullability)
392
    /// - `None` if the scalars have different data types
393
    ///
394
    /// # Ordering Rules
395
    /// When types match, the ordering follows these rules:
396
    /// - Null values are considered less than all non-null values
397
    /// - Non-null values are compared according to their natural ordering
398
    ///
399
    /// # Examples
400
    /// ```ignore
401
    /// // Same types compare successfully
402
    /// let a = Scalar::primitive(10i32, Nullability::NonNullable);
403
    /// let b = Scalar::primitive(20i32, Nullability::NonNullable);
404
    /// assert_eq!(a.partial_cmp(&b), Some(Ordering::Less));
405
    ///
406
    /// // Different types return None
407
    /// let int_scalar = Scalar::primitive(10i32, Nullability::NonNullable);
408
    /// let str_scalar = Scalar::utf8("hello", Nullability::NonNullable);
409
    /// assert_eq!(int_scalar.partial_cmp(&str_scalar), None);
410
    ///
411
    /// // Nulls are less than non-nulls
412
    /// let null = Scalar::null(DType::Primitive(PType::I32, Nullability::Nullable));
413
    /// let value = Scalar::primitive(0i32, Nullability::Nullable);
414
    /// assert_eq!(null.partial_cmp(&value), Some(Ordering::Less));
415
    /// ```
416
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
100,579✔
417
        if !self.dtype().eq_ignore_nullability(other.dtype()) {
100,579✔
418
            return None;
2✔
419
        }
100,577✔
420
        match self.dtype() {
100,577✔
421
            DType::Null => Some(Ordering::Equal),
×
422
            DType::Bool(_) => self.as_bool().partial_cmp(&other.as_bool()),
6,594✔
423
            DType::Primitive(..) => self.as_primitive().partial_cmp(&other.as_primitive()),
80,609✔
424
            DType::Decimal(..) => self.as_decimal().partial_cmp(&other.as_decimal()),
2,523✔
425
            DType::Utf8(_) => self.as_utf8().partial_cmp(&other.as_utf8()),
9,765✔
426
            DType::Binary(_) => self.as_binary().partial_cmp(&other.as_binary()),
78✔
427
            DType::Struct(..) => self.as_struct().partial_cmp(&other.as_struct()),
×
428
            DType::List(..) => self.as_list().partial_cmp(&other.as_list()),
×
429
            DType::Extension(_) => self.as_extension().partial_cmp(&other.as_extension()),
1,008✔
430
        }
431
    }
100,579✔
432
}
433

434
impl Hash for Scalar {
435
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
56,599✔
436
        match self.dtype() {
56,599✔
437
            DType::Null => self.dtype().hash(state), // Hash the dtype instead of the value
2✔
438
            DType::Bool(_) => self.as_bool().hash(state),
1,412✔
439
            DType::Primitive(..) => self.as_primitive().hash(state),
36,189✔
440
            DType::Decimal(..) => self.as_decimal().hash(state),
300✔
441
            DType::Utf8(_) => self.as_utf8().hash(state),
8,724✔
442
            DType::Binary(_) => self.as_binary().hash(state),
×
443
            DType::Struct(..) => self.as_struct().hash(state),
×
444
            DType::List(..) => self.as_list().hash(state),
1,308✔
445
            DType::Extension(_) => self.as_extension().hash(state),
8,664✔
446
        }
447
    }
56,599✔
448
}
449

450
impl AsRef<Self> for Scalar {
451
    fn as_ref(&self) -> &Self {
2,882,122✔
452
        self
2,882,122✔
453
    }
2,882,122✔
454
}
455

456
impl<T> From<Option<T>> for Scalar
457
where
458
    T: ScalarType,
459
    Scalar: From<T>,
460
{
461
    fn from(value: Option<T>) -> Self {
1,886,190✔
462
        value
1,886,190✔
463
            .map(Scalar::from)
1,886,190✔
464
            .map(|x| x.into_nullable())
1,886,190✔
465
            .unwrap_or_else(|| Scalar {
1,886,190✔
466
                dtype: T::dtype().as_nullable(),
168,794✔
467
                value: ScalarValue(InnerScalarValue::Null),
168,794✔
468
            })
168,794✔
469
    }
1,886,190✔
470
}
471

472
impl From<PrimitiveScalar<'_>> for Scalar {
473
    fn from(pscalar: PrimitiveScalar<'_>) -> Self {
2,925,938✔
474
        let dtype = pscalar.dtype().clone();
2,925,938✔
475
        let value = pscalar
2,925,938✔
476
            .pvalue()
2,925,938✔
477
            .map(|pvalue| ScalarValue(InnerScalarValue::Primitive(pvalue)))
2,925,938✔
478
            .unwrap_or_else(|| ScalarValue(InnerScalarValue::Null));
2,925,938✔
479
        Self::new(dtype, value)
2,925,938✔
480
    }
2,925,938✔
481
}
482

483
impl From<DecimalScalar<'_>> for Scalar {
484
    fn from(decimal_scalar: DecimalScalar<'_>) -> Self {
1✔
485
        let dtype = decimal_scalar.dtype().clone();
1✔
486
        let value = decimal_scalar
1✔
487
            .decimal_value()
1✔
488
            .map(|value| ScalarValue(InnerScalarValue::Decimal(value)))
1✔
489
            .unwrap_or_else(|| ScalarValue(InnerScalarValue::Null));
1✔
490
        Self::new(dtype, value)
1✔
491
    }
1✔
492
}
493

494
macro_rules! from_vec_for_scalar {
495
    ($T:ty) => {
496
        impl From<Vec<$T>> for Scalar {
497
            fn from(value: Vec<$T>) -> Self {
160✔
498
                Scalar {
499
                    dtype: DType::List(Arc::from(<$T>::dtype()), Nullability::NonNullable),
160✔
500
                    value: ScalarValue(InnerScalarValue::List(
501
                        value
160✔
502
                            .into_iter()
160✔
503
                            .map(Scalar::from)
160✔
504
                            .map(|s| s.into_value())
10,229✔
505
                            .collect::<Arc<[_]>>(),
160✔
506
                    )),
507
                }
508
            }
160✔
509
        }
510
    };
511
}
512

513
// no From<Vec<u8>> because it could either be a List or a Buffer
514
from_vec_for_scalar!(u16);
515
from_vec_for_scalar!(u32);
516
from_vec_for_scalar!(u64);
517
from_vec_for_scalar!(usize); // For usize only, we implicitly cast for better ergonomics.
518
from_vec_for_scalar!(i8);
519
from_vec_for_scalar!(i16);
520
from_vec_for_scalar!(i32);
521
from_vec_for_scalar!(i64);
522
from_vec_for_scalar!(f16);
523
from_vec_for_scalar!(f32);
524
from_vec_for_scalar!(f64);
525
from_vec_for_scalar!(String);
526
from_vec_for_scalar!(BufferString);
527
from_vec_for_scalar!(ByteBuffer);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc