facet_core/types/
scalar_affinities.rs

1use crate::OpaqueConst;
2
3/// Scalar affinity: what a scalar spiritually is: a number, a string, a bool, something else
4/// entirely?
5#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
6#[repr(C)]
7#[non_exhaustive]
8pub enum ScalarAffinity {
9    /// Number-like scalar affinity
10    Number(NumberAffinity),
11    /// String-like scalar affinity
12    String(StringAffinity),
13    /// Boolean scalar affinity
14    Boolean(BoolAffinity),
15    /// Empty scalar affinity
16    Empty(EmptyAffinity),
17    /// Socket address scalar affinity
18    SocketAddr(SocketAddrAffinity),
19    /// Ip Address scalar affinity
20    IpAddr(IpAddrAffinity),
21    /// Something you're not supposed to look inside of
22    Opaque(OpaqueAffinity),
23    /// Other scalar affinity
24    Other(OtherAffinity),
25}
26
27impl ScalarAffinity {
28    /// Returns a NumberAffinityBuilder
29    pub const fn number() -> NumberAffinityBuilder {
30        NumberAffinityBuilder::new()
31    }
32
33    /// Returns a StringAffinityBuilder
34    pub const fn string() -> StringAffinityBuilder {
35        StringAffinityBuilder::new()
36    }
37
38    /// Returns a BoolAffinityBuilder
39    pub const fn boolean() -> BoolAffinityBuilder {
40        BoolAffinityBuilder::new()
41    }
42
43    /// Returns an EmptyAffinityBuilder
44    pub const fn empty() -> EmptyAffinityBuilder {
45        EmptyAffinityBuilder::new()
46    }
47
48    /// Returns a SocketAddrAffinityBuilder
49    pub const fn socket_addr() -> SocketAddrAffinityBuilder {
50        SocketAddrAffinityBuilder::new()
51    }
52
53    /// Returns an IpAddrAffinityBuilder
54    pub const fn ip_addr() -> IpAddrAffinityBuilder {
55        IpAddrAffinityBuilder::new()
56    }
57
58    /// Returns an OpaqueAffinityBuilder
59    pub const fn opaque() -> OpaqueAffinityBuilder {
60        OpaqueAffinityBuilder::new()
61    }
62
63    /// Returns an OtherAffinityBuilder
64    pub const fn other() -> OtherAffinityBuilder {
65        OtherAffinityBuilder::new()
66    }
67}
68
69//////////////////////////////////////////////////////////////////////////////////////////
70// Affinities
71//////////////////////////////////////////////////////////////////////////////////////////
72
73/// Definition for number-like scalar affinities
74#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
75#[repr(C)]
76#[non_exhaustive]
77pub struct NumberAffinity {
78    /// Bit representation of numbers
79    pub bits: NumberBits,
80
81    /// Minimum representable value
82    pub min: OpaqueConst<'static>,
83
84    /// Maximum representable value
85    pub max: OpaqueConst<'static>,
86
87    /// Positive infinity representable value
88    pub positive_infinity: Option<OpaqueConst<'static>>,
89
90    /// Negative infinity representable value
91    pub negative_infinity: Option<OpaqueConst<'static>>,
92
93    /// Example NaN (Not a Number) value.
94    /// Why sample? Because there are many NaN values, and we need to provide a representative one.
95    pub nan_sample: Option<OpaqueConst<'static>>,
96
97    /// Positive zero representation. If there's only one zero, only set this one.
98    pub positive_zero: Option<OpaqueConst<'static>>,
99
100    /// Negative zero representation
101    pub negative_zero: Option<OpaqueConst<'static>>,
102}
103
104/// Represents whether a numeric type is signed or unsigned
105#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
106#[repr(C)]
107#[non_exhaustive]
108pub enum Signedness {
109    /// Signed numeric type
110    Signed,
111    /// Unsigned numeric type
112    Unsigned,
113}
114
115/// Bit representation of numbers
116#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
117#[repr(C)]
118#[non_exhaustive]
119pub enum NumberBits {
120    /// Integer number limits with specified number of bits
121    Integer {
122        /// Number of bits in the integer representation
123        bits: usize,
124        /// Whether the integer is signed or unsigned
125        sign: Signedness,
126    },
127    /// Floating-point number limits with specified sign, exponent and mantissa bits
128    Float {
129        /// Number of bits used for the sign (typically 1)
130        sign_bits: usize,
131        /// Number of bits used for the exponent
132        exponent_bits: usize,
133        /// Number of bits used for the mantissa (fraction part)
134        mantissa_bits: usize,
135    },
136    /// Fixed-point number limits with specified integer and fractional bits
137    Fixed {
138        /// Number of bits used for the sign (typically 0 or 1)
139        sign_bits: usize,
140        /// Number of bits used for the integer part
141        integer_bits: usize,
142        /// Number of bits used for the fractional part
143        fraction_bits: usize,
144    },
145}
146
147impl NumberAffinity {
148    /// Returns a builder for NumberAffinity
149    pub const fn builder() -> NumberAffinityBuilder {
150        NumberAffinityBuilder::new()
151    }
152}
153
154/// Builder for NumberAffinity
155#[repr(C)]
156pub struct NumberAffinityBuilder {
157    limits: Option<NumberBits>,
158    min: Option<OpaqueConst<'static>>,
159    max: Option<OpaqueConst<'static>>,
160    positive_infinity: Option<OpaqueConst<'static>>,
161    negative_infinity: Option<OpaqueConst<'static>>,
162    nan_sample: Option<OpaqueConst<'static>>,
163    positive_zero: Option<OpaqueConst<'static>>,
164    negative_zero: Option<OpaqueConst<'static>>,
165}
166
167impl NumberAffinityBuilder {
168    /// Creates a new NumberAffinityBuilder
169    #[allow(clippy::new_without_default)]
170    pub const fn new() -> Self {
171        Self {
172            limits: None,
173            min: None,
174            max: None,
175            positive_infinity: None,
176            negative_infinity: None,
177            nan_sample: None,
178            positive_zero: None,
179            negative_zero: None,
180        }
181    }
182
183    /// Sets the number limits as integer with specified bits and sign
184    pub const fn integer(mut self, bits: usize, sign: Signedness) -> Self {
185        self.limits = Some(NumberBits::Integer { bits, sign });
186        self
187    }
188
189    /// Sets the number limits as signed integer with specified bits
190    pub const fn signed_integer(self, bits: usize) -> Self {
191        self.integer(bits, Signedness::Signed)
192    }
193
194    /// Sets the number limits as unsigned integer with specified bits
195    pub const fn unsigned_integer(self, bits: usize) -> Self {
196        self.integer(bits, Signedness::Unsigned)
197    }
198
199    /// Sets the number limits as float with specified bits
200    pub const fn float(
201        mut self,
202        sign_bits: usize,
203        exponent_bits: usize,
204        mantissa_bits: usize,
205    ) -> Self {
206        self.limits = Some(NumberBits::Float {
207            sign_bits,
208            exponent_bits,
209            mantissa_bits,
210        });
211        self
212    }
213
214    /// Sets the number limits as fixed-point with specified bits
215    pub const fn fixed(
216        mut self,
217        sign_bits: usize,
218        integer_bits: usize,
219        fraction_bits: usize,
220    ) -> Self {
221        self.limits = Some(NumberBits::Fixed {
222            sign_bits,
223            integer_bits,
224            fraction_bits,
225        });
226        self
227    }
228
229    /// Sets the min value for the NumberAffinity
230    pub const fn min(mut self, min: OpaqueConst<'static>) -> Self {
231        self.min = Some(min);
232        self
233    }
234
235    /// Sets the max value for the NumberAffinity
236    pub const fn max(mut self, max: OpaqueConst<'static>) -> Self {
237        self.max = Some(max);
238        self
239    }
240
241    /// Sets the positive infinity value for the NumberAffinity
242    pub const fn positive_infinity(mut self, value: OpaqueConst<'static>) -> Self {
243        self.positive_infinity = Some(value);
244        self
245    }
246
247    /// Sets the negative infinity value for the NumberAffinity
248    pub const fn negative_infinity(mut self, value: OpaqueConst<'static>) -> Self {
249        self.negative_infinity = Some(value);
250        self
251    }
252
253    /// Sets the NaN sample value for the NumberAffinity
254    pub const fn nan_sample(mut self, value: OpaqueConst<'static>) -> Self {
255        self.nan_sample = Some(value);
256        self
257    }
258
259    /// Sets the positive zero value for the NumberAffinity
260    pub const fn positive_zero(mut self, value: OpaqueConst<'static>) -> Self {
261        self.positive_zero = Some(value);
262        self
263    }
264
265    /// Sets the negative zero value for the NumberAffinity
266    pub const fn negative_zero(mut self, value: OpaqueConst<'static>) -> Self {
267        self.negative_zero = Some(value);
268        self
269    }
270
271    /// Builds the ScalarAffinity
272    pub const fn build(self) -> ScalarAffinity {
273        ScalarAffinity::Number(NumberAffinity {
274            bits: self.limits.unwrap(),
275            min: self.min.unwrap(),
276            max: self.max.unwrap(),
277            positive_infinity: self.positive_infinity,
278            negative_infinity: self.negative_infinity,
279            nan_sample: self.nan_sample,
280            positive_zero: self.positive_zero,
281            negative_zero: self.negative_zero,
282        })
283    }
284}
285
286/// Definition for string-like scalar affinities
287#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
288#[repr(C)]
289#[non_exhaustive]
290pub struct StringAffinity {
291    /// Maximum inline length
292    pub max_inline_length: Option<usize>,
293}
294
295impl StringAffinity {
296    /// Returns a builder for StringAffinity
297    pub const fn builder() -> StringAffinityBuilder {
298        StringAffinityBuilder::new()
299    }
300}
301
302/// Builder for StringAffinity
303#[repr(C)]
304pub struct StringAffinityBuilder {
305    max_inline_length: Option<usize>,
306}
307
308impl StringAffinityBuilder {
309    /// Creates a new StringAffinityBuilder
310    #[allow(clippy::new_without_default)]
311    pub const fn new() -> Self {
312        Self {
313            max_inline_length: None,
314        }
315    }
316
317    /// Sets the max_inline_length for the StringAffinity
318    pub const fn max_inline_length(mut self, max_inline_length: usize) -> Self {
319        self.max_inline_length = Some(max_inline_length);
320        self
321    }
322
323    /// Builds the ScalarAffinity
324    pub const fn build(self) -> ScalarAffinity {
325        ScalarAffinity::String(StringAffinity {
326            max_inline_length: self.max_inline_length,
327        })
328    }
329}
330
331/// Definition for boolean scalar affinities
332#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
333#[repr(C)]
334#[non_exhaustive]
335pub struct BoolAffinity {}
336
337impl BoolAffinity {
338    /// Returns a builder for BoolAffinity
339    pub const fn builder() -> BoolAffinityBuilder {
340        BoolAffinityBuilder::new()
341    }
342}
343
344/// Builder for BoolAffinity
345#[repr(C)]
346pub struct BoolAffinityBuilder {}
347
348impl BoolAffinityBuilder {
349    /// Creates a new BoolAffinityBuilder
350    #[allow(clippy::new_without_default)]
351    pub const fn new() -> Self {
352        Self {}
353    }
354
355    /// Builds the ScalarAffinity
356    pub const fn build(self) -> ScalarAffinity {
357        ScalarAffinity::Boolean(BoolAffinity {})
358    }
359}
360
361/// Definition for empty scalar affinities
362#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
363#[repr(C)]
364#[non_exhaustive]
365pub struct EmptyAffinity {}
366
367impl EmptyAffinity {
368    /// Returns a builder for EmptyAffinity
369    pub const fn builder() -> EmptyAffinityBuilder {
370        EmptyAffinityBuilder::new()
371    }
372}
373
374/// Builder for EmptyAffinity
375#[repr(C)]
376pub struct EmptyAffinityBuilder {}
377
378impl EmptyAffinityBuilder {
379    /// Creates a new EmptyAffinityBuilder
380    #[allow(clippy::new_without_default)]
381    pub const fn new() -> Self {
382        Self {}
383    }
384
385    /// Builds the ScalarAffinity
386    pub const fn build(self) -> ScalarAffinity {
387        ScalarAffinity::Empty(EmptyAffinity {})
388    }
389}
390
391/// Definition for socket address scalar affinities
392#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
393#[repr(C)]
394#[non_exhaustive]
395pub struct SocketAddrAffinity {}
396
397impl SocketAddrAffinity {
398    /// Returns a builder for SocketAddrAffinity
399    pub const fn builder() -> SocketAddrAffinityBuilder {
400        SocketAddrAffinityBuilder::new()
401    }
402}
403
404/// Builder for SocketAddrAffinity
405#[repr(C)]
406pub struct SocketAddrAffinityBuilder {}
407
408impl SocketAddrAffinityBuilder {
409    /// Creates a new SocketAddrAffinityBuilder
410    #[allow(clippy::new_without_default)]
411    pub const fn new() -> Self {
412        Self {}
413    }
414
415    /// Builds the ScalarAffinity
416    pub const fn build(self) -> ScalarAffinity {
417        ScalarAffinity::SocketAddr(SocketAddrAffinity {})
418    }
419}
420
421/// Definition for IP address scalar affinities
422#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
423#[repr(C)]
424#[non_exhaustive]
425pub struct IpAddrAffinity {}
426
427impl IpAddrAffinity {
428    /// Returns a builder for IpAddrAffinity
429    pub const fn builder() -> IpAddrAffinityBuilder {
430        IpAddrAffinityBuilder::new()
431    }
432}
433
434/// Builder for IpAddrAffinity
435#[repr(C)]
436pub struct IpAddrAffinityBuilder {}
437
438impl IpAddrAffinityBuilder {
439    /// Creates a new IpAddrAffinityBuilder
440    #[allow(clippy::new_without_default)]
441    pub const fn new() -> Self {
442        Self {}
443    }
444
445    /// Builds the ScalarAffinity
446    pub const fn build(self) -> ScalarAffinity {
447        ScalarAffinity::IpAddr(IpAddrAffinity {})
448    }
449}
450
451/// Definition for opaque scalar affinities
452#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
453#[repr(C)]
454#[non_exhaustive]
455pub struct OpaqueAffinity {}
456
457impl OpaqueAffinity {
458    /// Returns a builder for OpaqueAffinity
459    pub const fn builder() -> OpaqueAffinityBuilder {
460        OpaqueAffinityBuilder::new()
461    }
462}
463
464/// Builder for OpaqueAffinity
465#[repr(C)]
466pub struct OpaqueAffinityBuilder {}
467
468impl OpaqueAffinityBuilder {
469    /// Creates a new OpaqueAffinityBuilder
470    #[allow(clippy::new_without_default)]
471    pub const fn new() -> Self {
472        Self {}
473    }
474
475    /// Builds the ScalarAffinity
476    pub const fn build(self) -> ScalarAffinity {
477        ScalarAffinity::Opaque(OpaqueAffinity {})
478    }
479}
480
481/// Definition for other scalar affinities
482#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
483#[repr(C)]
484#[non_exhaustive]
485pub struct OtherAffinity {}
486
487impl OtherAffinity {
488    /// Returns a builder for OtherAffinity
489    pub const fn builder() -> OtherAffinityBuilder {
490        OtherAffinityBuilder::new()
491    }
492}
493
494/// Builder for OtherAffinity
495#[repr(C)]
496pub struct OtherAffinityBuilder {}
497
498impl OtherAffinityBuilder {
499    /// Creates a new OtherAffinityBuilder
500    #[allow(clippy::new_without_default)]
501    pub const fn new() -> Self {
502        Self {}
503    }
504
505    /// Builds the ScalarAffinity
506    pub const fn build(self) -> ScalarAffinity {
507        ScalarAffinity::Other(OtherAffinity {})
508    }
509}