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

vortex-data / vortex / 16832413242

08 Aug 2025 02:04PM UTC coverage: 84.935% (+0.06%) from 84.877%
16832413242

Pull #4161

github

web-flow
Merge 04e9b0a07 into c88d9ada1
Pull Request #4161: feat(python): Add Arrow FFI streaming support to write API

50657 of 59642 relevant lines covered (84.94%)

568241.59 hits per line

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

58.82
/vortex-array/src/stats/precision.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use std::fmt::{Debug, Display, Formatter};
5

6
use vortex_dtype::DType;
7
use vortex_error::VortexResult;
8
use vortex_scalar::{Scalar, ScalarValue};
9

10
use crate::stats::precision::Precision::{Exact, Inexact};
11

12
/// A statistic has a precision `Exact` or `Inexact`. This represents uncertainty in that value.
13
/// Exact values are computed, where can inexact values are likely inferred from compute functions.
14
///
15
/// Inexact statistics form a range of possible values that the statistic could be.
16
/// This is statistic specific, for max this will be an upper bound. Meaning that the actual max
17
/// in an array is guaranteed to be less than or equal to the inexact value, but equal to the exact
18
/// value.
19
#[derive(Debug, PartialEq, Eq)]
20
pub enum Precision<T> {
21
    Exact(T),
22
    Inexact(T),
23
}
24

25
impl<T> Clone for Precision<T>
26
where
27
    T: Clone,
28
{
29
    fn clone(&self) -> Self {
1,717,899✔
30
        match self {
1,717,899✔
31
            Exact(e) => Exact(e.clone()),
1,714,226✔
32
            Inexact(ie) => Inexact(ie.clone()),
3,673✔
33
        }
34
    }
1,717,899✔
35
}
36

37
impl<T> Precision<Option<T>> {
38
    /// Transpose the `Option<Precision<T>>` into `Option<Precision<T>>`.
39
    pub fn transpose(self) -> Option<Precision<T>> {
336✔
40
        match self {
336✔
41
            Exact(Some(x)) => Some(Exact(x)),
292✔
42
            Inexact(Some(x)) => Some(Inexact(x)),
×
43
            _ => None,
44✔
44
        }
45
    }
336✔
46
}
47

48
impl<T> Precision<T>
49
where
50
    T: Copy,
51
{
52
    pub fn to_inexact(&self) -> Self {
×
53
        match self {
×
54
            Exact(v) => Exact(*v),
×
55
            Inexact(v) => Inexact(*v),
×
56
        }
57
    }
×
58
}
59

60
impl<T> Precision<T> {
61
    /// Creates an exact value
62
    pub fn exact<S: Into<T>>(s: S) -> Precision<T> {
174,181✔
63
        Exact(s.into())
174,181✔
64
    }
174,181✔
65

66
    /// Creates an inexact value
67
    pub fn inexact<S: Into<T>>(s: S) -> Precision<T> {
194✔
68
        Inexact(s.into())
194✔
69
    }
194✔
70

71
    /// Pushed the ref into the Precision enum
72
    pub fn as_ref(&self) -> Precision<&T> {
57,892✔
73
        match self {
57,892✔
74
            Exact(val) => Exact(val),
57,892✔
75
            Inexact(val) => Inexact(val),
×
76
        }
77
    }
57,892✔
78

79
    /// Converts `self` into an inexact bound
80
    pub fn into_inexact(self) -> Self {
2,112✔
81
        match self {
2,112✔
82
            Exact(val) => Inexact(val),
2,112✔
83
            Inexact(_) => self,
×
84
        }
85
    }
2,112✔
86

87
    /// Returns the exact value from the bound, if that value is inexact, otherwise `None`.
88
    pub fn as_exact(self) -> Option<T> {
85,337✔
89
        match self {
85,337✔
90
            Exact(val) => Some(val),
85,337✔
91
            _ => None,
×
92
        }
93
    }
85,337✔
94

95
    /// Returns the exact value from the bound, if that value is inexact, otherwise `None`.
96
    pub fn as_inexact(self) -> Option<T> {
×
97
        match self {
×
98
            Inexact(val) => Some(val),
×
99
            _ => None,
×
100
        }
101
    }
×
102

103
    /// True iff self == Exact(_)
104
    pub fn is_exact(&self) -> bool {
26,959✔
105
        matches!(self, Exact(_))
26,959✔
106
    }
26,959✔
107

108
    /// Map the value of either precision value
109
    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Precision<U> {
1,732,954✔
110
        match self {
1,732,954✔
111
            Exact(value) => Exact(f(value)),
1,728,459✔
112
            Inexact(value) => Inexact(f(value)),
4,495✔
113
        }
114
    }
1,732,954✔
115

116
    /// Zip two `Precision` values into a tuple, keeping the inexactness if any.
117
    pub fn zip<U>(self, other: Precision<U>) -> Precision<(T, U)> {
555✔
118
        match (self, other) {
555✔
119
            (Exact(lhs), Exact(rhs)) => Exact((lhs, rhs)),
3✔
120
            (Inexact(lhs), Exact(rhs))
×
121
            | (Exact(lhs), Inexact(rhs))
192✔
122
            | (Inexact(lhs), Inexact(rhs)) => Inexact((lhs, rhs)),
552✔
123
        }
124
    }
555✔
125

126
    /// Similar to `map` but handles fucntions that can fail.
127
    pub fn try_map<U, F: FnOnce(T) -> VortexResult<U>>(self, f: F) -> VortexResult<Precision<U>> {
×
128
        let precision = match self {
×
129
            Exact(value) => Exact(f(value)?),
×
130
            Inexact(value) => Inexact(f(value)?),
×
131
        };
132
        Ok(precision)
×
133
    }
×
134

135
    /// Unwrap the underlying value
136
    pub fn into_inner(self) -> T {
26,406✔
137
        match self {
26,406✔
138
            Exact(val) | Inexact(val) => val,
26,406✔
139
        }
140
    }
26,406✔
141
}
142

143
impl<T: Display> Display for Precision<T> {
144
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
×
145
        match self {
×
146
            Exact(v) => {
×
147
                write!(f, "{v}")
×
148
            }
149
            Inexact(v) => {
×
150
                write!(f, "~{v}")
×
151
            }
152
        }
153
    }
×
154
}
155

156
impl<T: PartialEq> PartialEq<T> for Precision<T> {
157
    fn eq(&self, other: &T) -> bool {
1✔
158
        match self {
1✔
159
            Exact(v) => v == other,
1✔
160
            _ => false,
×
161
        }
162
    }
1✔
163
}
164

165
impl Precision<ScalarValue> {
166
    pub fn into_scalar(self, dtype: DType) -> Precision<Scalar> {
×
167
        self.map(|v| Scalar::new(dtype, v))
×
168
    }
×
169
}
170

171
impl Precision<&ScalarValue> {
172
    pub fn into_scalar(self, dtype: DType) -> Precision<Scalar> {
×
173
        self.map(|v| Scalar::new(dtype, v.clone()))
×
174
    }
×
175
}
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

© 2026 Coveralls, Inc