Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions crates/stackable-operator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@ All notable changes to this project will be documented in this file.

### Added

- Implement `Deref` for `kvp::Key` to be more ergonomic to use ([#1182]).
- Add support for specifying a `clientAuthenticationMethod` for OIDC ([#1178]).
This was originally done in [#1158] and had been reverted in [#1170].

### Removed

- BREAKING: Remove unused `add_prefix`, `try_add_prefix`, `set_name`, and `try_set_name` associated
functions from `kvp::Key` to disallow mutable access to inner values ([#1182]).

[#1178]: https://github.com/stackabletech/operator-rs/pull/1178
[#1182]: https://github.com/stackabletech/operator-rs/pull/1182

## [0.108.0] - 2026-03-10

Expand Down
73 changes: 34 additions & 39 deletions crates/stackable-operator/src/kvp/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ pub enum KeyError {
/// [k8s-labels]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Key {
/// A cached and formatted representation of a [`Key`] as a [`String`], which enables the
/// implementation of [`Deref`], instead of constructing a new [`String`] every time the string
/// representation of a key is needed.
///
/// ### Safety
///
/// This is safe to do (and cache it), because [`Key`] doesn't provide any **mutable** access
/// to the inner values.
string: String,

prefix: Option<KeyPrefix>,
name: KeyName,
}
Expand All @@ -80,12 +90,22 @@ impl FromStr for Key {
_ => return NestedPrefixSnafu.fail(),
};

let prefix = prefix
.map(KeyPrefix::from_str)
.transpose()
.context(KeyPrefixSnafu)?;

let name = KeyName::from_str(name).context(KeyNameSnafu)?;

let string = match prefix {
Some(ref prefix) => format!("{prefix}/{name}"),
None => format!("{name}"),
};

let key = Self {
prefix: prefix
.map(KeyPrefix::from_str)
.transpose()
.context(KeyPrefixSnafu)?,
name: KeyName::from_str(name).context(KeyNameSnafu)?,
string,
prefix,
name,
};

Ok(key)
Expand All @@ -102,10 +122,15 @@ impl TryFrom<&str> for Key {

impl Display for Key {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.prefix {
Some(prefix) => write!(f, "{}/{}", prefix, self.name),
None => write!(f, "{}", self.name),
}
write!(f, "{key}", key = self.string)
}
}

impl Deref for Key {
type Target = str;

fn deref(&self) -> &Self::Target {
self.string.as_str()
}
}

Expand All @@ -126,21 +151,6 @@ impl Key {
self.prefix.as_ref()
}

/// Adds or replaces the key prefix. This takes a parsed and validated
/// [`KeyPrefix`] as a parameter. If instead you want to use a raw value,
/// use the [`Key::try_add_prefix()`] function instead.
pub fn add_prefix(&mut self, prefix: KeyPrefix) {
self.prefix = Some(prefix)
}

/// Adds or replaces the key prefix by parsing and validation raw input. If
/// instead you already have a parsed and validated [`KeyPrefix`], use the
/// [`Key::add_prefix()`] function instead.
pub fn try_add_prefix(&mut self, prefix: impl AsRef<str>) -> Result<&mut Self, KeyError> {
self.prefix = Some(KeyPrefix::from_str(prefix.as_ref()).context(KeyPrefixSnafu)?);
Ok(self)
}

/// Retrieves the key's name.
///
/// ```
Expand All @@ -156,21 +166,6 @@ impl Key {
pub fn name(&self) -> &KeyName {
&self.name
}

/// Sets the key name. This takes a parsed and validated [`KeyName`] as a
/// parameter. If instead you want to use a raw value, use the
/// [`Key::try_set_name()`] function instead.
pub fn set_name(&mut self, name: KeyName) {
self.name = name
}

/// Sets the key name by parsing and validation raw input. If instead you
/// already have a parsed and validated [`KeyName`], use the
/// [`Key::set_name()`] function instead.
pub fn try_set_name(&mut self, name: impl AsRef<str>) -> Result<&mut Self, KeyError> {
self.name = KeyName::from_str(name.as_ref()).context(KeyNameSnafu)?;
Ok(self)
}
}

/// The error type for key prefix parsing/validation operations.
Expand Down
Loading