Skip to content

Commit

Permalink
Doc cleanup for label selectors (#1542)
Browse files Browse the repository at this point in the history
* Doc cleanup for label selectors

Mostly a quick overview to make it as concise as possible.

The original was already very nice, just broke up paragraphs, imports, and added missing strings where they were needed on UI.

Signed-off-by: clux <sszynrae@gmail.com>

* fix that one import i didn't test

Signed-off-by: clux <sszynrae@gmail.com>

* fix new clippy doc warning while fixing docs

Signed-off-by: clux <sszynrae@gmail.com>

---------

Signed-off-by: clux <sszynrae@gmail.com>
  • Loading branch information
clux authored Jul 20, 2024
1 parent 1816fd8 commit 2fe7219
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 53 deletions.
86 changes: 41 additions & 45 deletions kube-core/src/labels.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![allow(missing_docs)]
//! Type safe label selector logic
use core::fmt;
use k8s_openapi::apimachinery::pkg::apis::meta::v1::{LabelSelector, LabelSelectorRequirement};
use serde::{Deserialize, Serialize};
Expand All @@ -25,9 +25,7 @@ pub struct ParseExpressionError(pub String);
// local type aliases
type Expressions = Vec<Expression>;

/// Selector extension trait for querying selector like objects
///
/// Only implemented by `Selector` and `Expression`.
/// Selector extension trait for querying selector-like objects
pub trait SelectorExt: private::Sealed {
/// Collection type to compare with self
type Search;
Expand All @@ -36,13 +34,13 @@ pub trait SelectorExt: private::Sealed {
///
/// ```
/// use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
/// use crate::kube_core::SelectorExt;
/// use crate::kube_core::Selector;
/// use kube_core::ParseExpressionError;
/// use kube::core::{SelectorExt, Selector};
/// # use std::collections::BTreeMap;
///
/// let selector: Selector = LabelSelector::default().try_into()?;
/// selector.matches(&Default::default());
/// # Ok::<(), ParseExpressionError>(())
/// let search = BTreeMap::from([("app".to_string(), "myapp".to_string())]);
/// selector.matches(&search);
/// # Ok::<(), kube_core::ParseExpressionError>(())
/// ```
fn matches(&self, on: &Self::Search) -> bool;
}
Expand All @@ -53,69 +51,65 @@ pub enum Expression {
/// Key exists and in set:
///
/// ```
/// use kube_core::Expression;
///
/// let exp = Expression::In("foo".into(), ["bar".into(), "baz".into()].into()).to_string();
/// assert_eq!(exp, "foo in (bar,baz)");
/// let exp = Expression::In("foo".into(), vec!["bar".into(), "baz".into()].into_iter().collect()).to_string();
/// assert_eq!(exp, "foo in (bar,baz)");
/// # use kube_core::Expression;
/// let exp = Expression::In("foo".into(), ["bar".into(), "baz".into()].into());
/// assert_eq!(exp.to_string(), "foo in (bar,baz)");
/// let exp = Expression::In("foo".into(), ["bar".into(), "baz".into()].into_iter().collect());
/// assert_eq!(exp.to_string(), "foo in (bar,baz)");
/// ```
In(String, BTreeSet<String>),

/// Key does not exists or not in set:
///
/// ```
/// use kube_core::Expression;
///
/// let exp = Expression::NotIn("foo".into(), ["bar".into(), "baz".into()].into()).to_string();
/// assert_eq!(exp, "foo notin (bar,baz)");
/// let exp = Expression::NotIn("foo".into(), vec!["bar".into(), "baz".into()].into_iter().collect()).to_string();
/// assert_eq!(exp, "foo notin (bar,baz)");
/// # use kube_core::Expression;
/// let exp = Expression::NotIn("foo".into(), ["bar".into(), "baz".into()].into());
/// assert_eq!(exp.to_string(), "foo notin (bar,baz)");
/// let exp = Expression::NotIn("foo".into(), ["bar".into(), "baz".into()].into_iter().collect());
/// assert_eq!(exp.to_string(), "foo notin (bar,baz)");
/// ```
NotIn(String, BTreeSet<String>),

/// Key exists and is equal:
///
/// ```
/// use kube_core::Expression;
///
/// let exp = Expression::Equal("foo".into(), "bar".into()).to_string();
/// assert_eq!(exp, "foo=bar")
/// # use kube_core::Expression;
/// let exp = Expression::Equal("foo".into(), "bar".into());
/// assert_eq!(exp.to_string(), "foo=bar")
/// ```
Equal(String, String),

/// Key does not exists or is not equal:
///
/// ```
/// use kube_core::Expression;
///
/// let exp = Expression::NotEqual("foo".into(), "bar".into()).to_string();
/// assert_eq!(exp, "foo!=bar")
/// # use kube_core::Expression;
/// let exp = Expression::NotEqual("foo".into(), "bar".into());
/// assert_eq!(exp.to_string(), "foo!=bar")
/// ```
NotEqual(String, String),

/// Key exists:
///
/// ```
/// use kube_core::Expression;
///
/// let exp = Expression::Exists("foo".into()).to_string();
/// assert_eq!(exp, "foo")
/// # use kube_core::Expression;
/// let exp = Expression::Exists("foo".into());
/// assert_eq!(exp.to_string(), "foo")
/// ```
Exists(String),

/// Key does not exist:
///
/// ```
/// use kube_core::Expression;
///
/// let exp = Expression::DoesNotExist("foo".into()).to_string();
/// assert_eq!(exp, "!foo")
/// # use kube_core::Expression;
/// let exp = Expression::DoesNotExist("foo".into());
/// assert_eq!(exp.to_string(), "!foo")
/// ```
DoesNotExist(String),
}

/// Perform selection on a list of expressions
///
/// Can be injected into [`WatchParams`](crate::params::WatchParams::labels_from) or [`ListParams`](crate::params::ListParams::labels_from).
#[derive(Clone, Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
pub struct Selector(Expressions);

Expand All @@ -130,25 +124,27 @@ impl Selector {
Self(map.into_iter().map(|(k, v)| Expression::Equal(k, v)).collect())
}

/// Indicates whether this label selector matches all pods
/// Indicates whether this label selector matches everything
pub fn selects_all(&self) -> bool {
self.0.is_empty()
}

/// Extend the list of expressions for the selector
///
/// ```
/// use kube_core::Selector;
/// use kube_core::Expression;
/// use kube::core::{Selector, Expression};
/// use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
/// use kube_core::ParseExpressionError;
///
/// let label_selector: Selector = LabelSelector::default().try_into()?;
/// let mut selector = &mut Selector::default();
/// selector = selector.extend(Expression::Equal("environment".into(), "production".into()));
/// let mut selector = Selector::default();
///
/// // Extend from expressions:
/// selector.extend(Expression::Equal("environment".into(), "production".into()));
/// selector.extend([Expression::Exists("bar".into()), Expression::Exists("foo".into())].into_iter());
///
/// // Extend from native selectors:
/// let label_selector: Selector = LabelSelector::default().try_into()?;
/// selector.extend(label_selector);
/// # Ok::<(), ParseExpressionError>(())
/// # Ok::<(), kube_core::ParseExpressionError>(())
/// ```
pub fn extend(&mut self, exprs: impl IntoIterator<Item = Expression>) -> &mut Self {
self.0.extend(exprs);
Expand Down
18 changes: 12 additions & 6 deletions kube-core/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,16 @@ impl ListParams {
/// Configure typed selectors from [`Selector`](crate::Selector) and [`Expression`](crate::Expression) lists.
///
/// ```
/// use kube::api::ListParams;
/// use kube_core::{Expression, Selector, ParseExpressionError};
/// use kube::core::{Expression, Selector, ParseExpressionError};
/// # use kube::core::params::ListParams;
/// use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
///
/// // From expressions
/// let selector: Selector = Expression::In("env".into(), ["development".into(), "sandbox".into()].into()).into();
/// let lp = ListParams::default().labels_from(&selector);
/// let lp = ListParams::default().labels_from(&Expression::Exists("foo".into()).into());
/// // Alternatively the raw LabelSelector is accepted
///
/// // Native LabelSelector
/// let selector: Selector = LabelSelector::default().try_into()?;
/// let lp = ListParams::default().labels_from(&selector);
/// # Ok::<(), ParseExpressionError>(())
Expand Down Expand Up @@ -456,13 +459,16 @@ impl WatchParams {
/// Configure typed selectors from [`Selector`](crate::Selector) and [`Expression`](crate::Expression) lists.
///
/// ```
/// use kube::api::WatchParams;
/// use kube_core::{Expression, Selector, ParseExpressionError};
/// use kube::core::{Expression, Selector, ParseExpressionError};
/// # use kube::core::params::WatchParams;
/// use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
///
/// // From expressions
/// let selector: Selector = Expression::In("env".into(), ["development".into(), "sandbox".into()].into()).into();
/// let wp = WatchParams::default().labels_from(&selector);
/// let wp = WatchParams::default().labels_from(&Expression::Exists("foo".into()).into());
/// // Alternatively the raw LabelSelector is accepted
///
/// // Native LabelSelector
/// let selector: Selector = LabelSelector::default().try_into()?;
/// let wp = WatchParams::default().labels_from(&selector);
/// # Ok::<(), ParseExpressionError>(())
Expand Down
3 changes: 1 addition & 2 deletions kube-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,7 @@ mod custom_resource;
/// - [Serde/Schemars Attributes](https://graham.cool/schemars/examples/3-schemars_attrs/) (no need to duplicate serde renames)
/// - [`#[schemars(schema_with = "func")]`](https://graham.cool/schemars/examples/7-custom_serialization/) (e.g. like in the [`crd_derive` example](https://github.com/kube-rs/kube/blob/main/examples/crd_derive.rs))
/// - `impl JsonSchema` on a type / newtype around external type. See [#129](https://github.com/kube-rs/kube/issues/129#issuecomment-750852916)
/// - [`#[garde(...)]` field attributes for client-side validation](https://github.com/jprochazk/garde) (see [`crd_api`
/// example](https://github.com/kube-rs/kube/blob/main/examples/crd_api.rs))
/// - [`#[garde(...)]` field attributes for client-side validation](https://github.com/jprochazk/garde) (see [`crd_api` example](https://github.com/kube-rs/kube/blob/main/examples/crd_api.rs))
///
/// You might need to override parts of the schemas (for fields in question) when you are:
/// - **using complex enums**: enums do not currently generate [structural schemas](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema), so kubernetes won't support them by default
Expand Down

0 comments on commit 2fe7219

Please sign in to comment.