Skip to content

Commit 845c022

Browse files
committed
docs: Start writing doc comments
1 parent d64bf0e commit 845c022

File tree

1 file changed

+65
-0
lines changed
  • crates/stackable-operator/src/quantity

1 file changed

+65
-0
lines changed

crates/stackable-operator/src/quantity/mod.rs

+65
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! This module contains types and functions to parse and handle Kubernetes quantities.
2+
13
use std::{
24
fmt::{Display, Write},
35
num::ParseFloatError,
@@ -29,6 +31,69 @@ pub enum ParseQuantityError {
2931
InvalidSuffix { source: ParseSuffixError },
3032
}
3133

34+
/// Quantity is a representation of a number with a suffix / format.
35+
///
36+
/// This type makes it possible to parse Kubernetes quantity strings like '12Ki', '2M, '1.5e2', or
37+
/// '0'. This is done by storing the parsed data as two separate values: the `value` and the
38+
/// `suffix`. The parsing is implemented according to the serialization format laid out in the
39+
/// Kubernetes [source code][quantity-format]. Roughly, the format looks like this:
40+
///
41+
/// ```plain
42+
/// quantity ::= <signedNumber><suffix>
43+
/// suffix ::= <binaryMultiple> | <decimalMultiple> | <decimalExponent>
44+
/// binaryMultiple ::= Ki | Mi | Gi | Ti | Pi | Ei
45+
/// decimalMultiple ::= m | "" | k | M | G | T | P | E
46+
/// decimalExponent ::= "e" <signedNumber> | "E" <signedNumber>
47+
/// ```
48+
///
49+
/// Generally speaking, this implementation very closely resembles the original upstream Go
50+
/// implementation of the Kubernetes project. However there are a few differences which boil down
51+
/// to being easier to use / implement using Rust and safety. These differences in addition to
52+
/// general notes on the implementation are detailed below:
53+
///
54+
/// #### Suffixes
55+
///
56+
/// It should be noted that the decimal multiple contains `""` (an empty string / no suffix). This
57+
/// is why one might think that the suffix is optional. Strictly speaking, it is not optional, but
58+
/// a missing / empty suffix maps to a decimal multiple with a scaling factor of 1000^0. The
59+
/// following section goes into more detail about the scaling factors.
60+
///
61+
/// Instead of marking the `suffix` field as optional by using [`Option`], it instead maps the empty
62+
/// suffix to the [`DecimalMultiple::Empty`] variant. This eases implementing safe mathematical (like
63+
/// scaling up/down, addition or division) operations on [`Quantity`].
64+
///
65+
/// The [`Suffix`] enum represents the three different supported suffixes. Each suffix uses a
66+
/// specific base and exponent for it's scaling factor:
67+
///
68+
/// - The [`BinaryMultiple`] uses a base of 2 and exponents of 10s.
69+
/// - The [`DecimalMultiple`] uses a base of 10 and exponents of 3s.
70+
/// - The [`DecimalExponent`] uses a base of 10 and exponents defined using the
71+
/// [scientific notation][sci-notation].
72+
///
73+
/// #### Mathematical operations
74+
///
75+
/// Similar to to upstream implementation, math operations can change the suffix / format.
76+
/// Additionally, it is necessary to change the suffix of the right-hand-side in binary operations
77+
/// before doing the actual operation (like addition).
78+
///
79+
/// - **Example 1:** `0Ki + 1Mi` - In this example, the lhs has the value **0**. The exact suffix is
80+
/// irrelevant, but note that it might be different from the suffix of the rhs. Since the value is
81+
/// zero, we can safely update the suffix of the lhs to `Mi` and continue by adding **1** to the
82+
/// lhs. The final result is then `1Mi`.
83+
/// - **Example 2:** `1024Ki + 1Mi` - Here, the lhs is not zero, so we cannot safely update the
84+
/// suffix. Instead, we need to scale the rhs to the appropriate suffix, `Ki` in this example.
85+
/// Afterwards the addition of both values can be done. The final result is `2048Ki`. If needed,
86+
/// this can be scaled to `Mi`, resulting in `2Mi` as expected.
87+
///
88+
/// #### Precision
89+
///
90+
/// The upstream implementation uses infinite-precision arithmetic to be able to store very large
91+
/// values, up to 2^63-1. This implementation **does not** use infinite-precision arithmetic. The
92+
/// biggest value which can be safely expresses is [`f64::MAX`]. This value is deemed plenty for
93+
/// now, but there is always the possibility of using infinite-precision implementation as well.
94+
///
95+
/// [quantity-format]: https://github.com/kubernetes/apimachinery/blob/3e8e52d6a1259ada73f63c1c7d1fad39d4ba9fb4/pkg/api/resource/quantity.go#L39-L59
96+
/// [sci-notation]: https://en.wikipedia.org/wiki/Scientific_notation#E_notation
3297
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
3398
pub struct Quantity {
3499
// FIXME (@Techassi): Support arbitrary-precision numbers

0 commit comments

Comments
 (0)