Skip to content

Commit bf157a3

Browse files
adwk67claude
andcommitted
feat: add framework macros and validated type definitions
Introduce the framework module with validated type wrappers that enforce constraints at parse time rather than at each use site. Includes attributed_string_type macro for generating validated newtypes, and typed wrappers for Kubernetes (NamespaceName, Uid) and operator (ProductName, OperatorName, etc.) concepts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 16f6693 commit bf157a3

12 files changed

Lines changed: 1555 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 205 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const_format = "0.2"
2323
fnv = "1.0"
2424
futures = { version = "0.3", features = ["compat"] }
2525
indoc = "2.0"
26+
regex = "1"
2627
rstest = "0.26"
2728
semver = "1.0"
2829
serde = { version = "1.0", features = ["derive"] }
@@ -32,6 +33,7 @@ snafu = "0.9"
3233
strum = { version = "0.28", features = ["derive"] }
3334
tokio = { version = "1.40", features = ["full"] }
3435
tracing = "0.1"
36+
uuid = { version = "1.16", features = ["v4"] }
3537

3638
[patch."https://github.com/stackabletech/operator-rs.git"]
3739
# stackable-operator = { git = "https://github.com/stackabletech//operator-rs.git", branch = "main" }

rust/operator-binary/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ indoc.workspace = true
2121
serde.workspace = true
2222
serde_json.workspace = true
2323
serde_yaml.workspace = true
24+
regex.workspace = true
2425
snafu.workspace = true
2526
strum.workspace = true
2627
tokio.workspace = true
2728
tracing.workspace = true
29+
uuid.workspace = true
2830

2931
[build-dependencies]
3032
built.workspace = true
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//! Additions to stackable-operator
2+
//!
3+
//! Functions in stackable-operator usually accept generic types like strings and validate the
4+
//! parameters as late as possible. Therefore, nearly all functions have to return a [`Result`] and
5+
//! errors are returned along the call chain. That makes error handling complex because every
6+
//! module re-packages the received error. Also, the validation is repeated if the value is used in
7+
//! different function calls. Sometimes, validation is not necessary if constant values are used,
8+
//! e.g. the name of the operator.
9+
//!
10+
//! This operator uses a different approach. The incoming values are validated as early as possible
11+
//! and wrapped in a fail-safe type. This type is then used along the call chain, validation is not
12+
//! necessary anymore and functions without side effects do not need to return a [`Result`].
13+
//!
14+
//! However, this operator uses stackable-operator and at the interface, the fail-safe types must
15+
//! be unwrapped and the [`Result`] returned by the stackable-operator function must be handled.
16+
//! This is done by calling [`Result::expect`] which requires thorough testing.
17+
//!
18+
//! When the development of this module has progressed and changes become less frequent, then this
19+
//! module can be incorporated into stackable-operator. The module structure should already
20+
//! resemble the one of stackable-operator.
21+
22+
use types::kubernetes::Uid;
23+
24+
pub mod macros;
25+
pub mod types;
26+
27+
/// Has a non-empty name
28+
///
29+
/// Useful as an object reference; Should not be used to create an object because the name could
30+
/// violate the naming constraints (e.g. maximum length) of the object.
31+
pub trait HasName {
32+
#[allow(dead_code)]
33+
fn to_name(&self) -> String;
34+
}
35+
36+
/// Has a Kubernetes UID
37+
#[allow(dead_code)]
38+
pub trait HasUid {
39+
fn to_uid(&self) -> Uid;
40+
}
41+
42+
/// The name is a valid label value
43+
#[allow(dead_code)]
44+
pub trait NameIsValidLabelValue {
45+
fn to_label_value(&self) -> String;
46+
}

0 commit comments

Comments
 (0)