Skip to main content

TransformFunction

Struct TransformFunction 

Source
pub struct TransformFunction(/* private fields */);
Expand description

A thread-safe wrapper around a transform function that can modify inventory entities.

TransformFunction encapsulates custom logic for dynamically transforming hosts, groups, and defaults in an inventory. It provides a flexible mechanism to modify inventory data based on runtime conditions, external configuration, or custom business logic without altering the underlying inventory structure.

The wrapper uses Arc for thread-safe reference counting, enabling the transform function to be shared across multiple threads and cloned efficiently. All clones share the same underlying transform logic.

§Transform Types

There are two ways to create a TransformFunction:

  1. Host-only transform - Using new(), which accepts a closure that only transforms hosts. Groups and defaults pass through unchanged.

  2. Full transform - Using new_full(), which accepts a type implementing the Transform trait, allowing custom transformation of hosts, groups, and defaults.

§When Transforms Are Applied

Transforms are applied lazily when accessing inventory entities through:

  • Inventory::hosts() - Returns a HostsView that applies transforms on access
  • Inventory::groups() - Returns a GroupsView that applies transforms on access
  • Inventory::defaults() - Returns transformed defaults
  • Inventory::resolve_host() - Applies transforms to the resolved host

Host and group transform results are cached to improve performance on subsequent accesses. Resolved hosts and connection parameters are also cached by Inventory. Defaults are transformed lazily on each Inventory::defaults() call and are not stored in a dedicated cache.

§Thread Safety

The Clone implementation creates a new reference to the same underlying transform function, not a deep copy. All clones share the same transform logic and can be safely used across threads.

§Examples

§Host-only Transform

// Create a transform that modifies the port for all hosts
let transform = TransformFunction::new(|host, _options| {
    host.to_builder()
        .port(2222)
        .build()
});

let mut hosts = Hosts::new();
hosts.add_host("router1", Host::builder().hostname("10.0.0.1").port(22).build());

let inventory = Inventory::builder()
    .hosts(hosts)
    .transform_function(transform)
    .build();

// Transform is applied when accessing the host
let host = inventory.hosts().get("router1").unwrap();
assert_eq!(host.port(), Some(2222));

§Full Transform with Options

struct CustomTransform;

impl Transform for CustomTransform {
    fn transform_host(&self, host: &Host, options: Option<&TransformFunctionOptions>) -> Host {
        // Access transform options if provided
        if let Some(opts) = options {
            if let Some(prefix) = opts.get("hostname_prefix").and_then(|v| v.as_str()) {
                if let Some(hostname) = host.hostname() {
                    return host.to_builder()
                        .hostname(format!("{}{}", prefix, hostname))
                        .build();
                }
            }
        }
        host.clone()
    }

    fn transform_group(&self, group: &Group, _options: Option<&TransformFunctionOptions>) -> Group {
        // Custom group transformation logic
        group.clone()
    }
}

let transform = TransformFunction::new_full(CustomTransform);
let options = TransformFunctionOptions::new(
    serde_json::json!({"hostname_prefix": "prod-"})
);

let mut hosts = Hosts::new();
hosts.add_host("router1", Host::builder().hostname("router1").build());

let inventory = Inventory::builder()
    .hosts(hosts)
    .transform_function(transform)
    .transform_function_options(options)
    .build();

let host = inventory.hosts().get("router1").unwrap();
assert_eq!(host.hostname(), Some("prod-router1"));

§Cloning and Sharing

let transform = TransformFunction::new(|host: &Host, _| host.clone());

// Cloning creates a new reference to the same transform
let transform_clone = transform.clone();

// Both can be used independently and share the same underlying logic

Implementations§

Source§

impl TransformFunction

Source

pub fn new<F>(func: F) -> Self
where F: Fn(&Host, Option<&TransformFunctionOptions>) -> Host + Send + Sync + 'static,

Creates a new transform function that only modifies hosts.

This is a convenience constructor for the common case where you only need to transform hosts. Groups and defaults will pass through unchanged. The provided closure receives a reference to the host and optional transform options, and should return a new Host instance with the desired modifications.

§Type Parameters
  • F - A closure type that takes (&Host, Option<&TransformFunctionOptions>) and returns a Host. The closure must be Send + Sync + 'static to allow thread-safe sharing across the inventory.
§Parameters
  • func - A closure that implements the host transformation logic. It receives:
    • &Host - A reference to the host being transformed
    • Option<&TransformFunctionOptions> - Optional configuration data for the transform
§Returns

Returns a new TransformFunction that applies the provided closure to hosts while leaving groups and defaults unchanged.

§Examples
// Simple transform that sets a default port
let transform = TransformFunction::new(|host, _options| {
    if host.port().is_none() {
        host.to_builder().port(22).build()
    } else {
        host.clone()
    }
});
// Transform using options
let transform = TransformFunction::new(|host, options| {
    if let Some(opts) = options {
        if let Some(default_port) = opts.get("default_port").and_then(|v| v.as_u64()) {
            if host.port().is_none() {
                return host.to_builder().port(default_port as u16).build();
            }
        }
    }
    host.clone()
});
Source

pub fn new_full<T>(transform: T) -> Self
where T: Transform + 'static,

Creates a new transform function from a type implementing the Transform trait.

This constructor allows for full control over transformation of hosts, groups, and defaults. Use this when you need to implement custom transformation logic for all inventory entity types, or when you need to maintain state across transformations.

§Type Parameters
  • T - A type implementing the Transform trait. The type must be 'static to allow it to be stored in the Arc wrapper.
§Parameters
  • transform - An instance of a type implementing Transform. The instance will be wrapped in an Arc for thread-safe sharing.
§Returns

Returns a new TransformFunction that applies the provided Transform implementation to hosts, groups, and defaults.

§Examples
struct EnvironmentTransform {
    environment: String,
}

impl Transform for EnvironmentTransform {
    fn transform_host(&self, host: &Host, _options: Option<&TransformFunctionOptions>) -> Host {
        // Prefix hostname with environment
        if let Some(hostname) = host.hostname() {
            host.to_builder()
                .hostname(format!("{}-{}", self.environment, hostname))
                .build()
        } else {
            host.clone()
        }
    }

    fn transform_group(&self, group: &Group, _options: Option<&TransformFunctionOptions>) -> Group {
        // Apply environment-specific group modifications
        group.clone()
    }

    fn transform_defaults(&self, defaults: &Defaults, _options: Option<&TransformFunctionOptions>) -> Defaults {
        // Apply environment-specific defaults
        defaults.clone()
    }
}

let transform = TransformFunction::new_full(EnvironmentTransform {
    environment: "prod".to_string(),
});
Source

pub fn transform_host( &self, host: &Host, options: Option<&TransformFunctionOptions>, ) -> Host

Applies the transform function to a host.

This method delegates to the underlying Transform implementation to modify the provided host according to the transform logic. It’s primarily used internally by the inventory system when accessing hosts through views or during resolution.

§Parameters
  • host - A reference to the host to transform
  • options - Optional configuration data to pass to the transform function
§Returns

Returns a new Host instance with transformations applied. If no transform logic is defined for hosts, returns a clone of the input host.

§Examples
let transform = TransformFunction::new(|host, _| {
    host.to_builder().port(2222).build()
});

let host = Host::builder().hostname("10.0.0.1").build();
let transformed = transform.transform_host(&host, None);
assert_eq!(transformed.port(), Some(2222));
Source

pub fn transform_group( &self, group: &Group, options: Option<&TransformFunctionOptions>, ) -> Group

Applies the transform function to a group.

This method delegates to the underlying Transform implementation to modify the provided group according to the transform logic. It’s primarily used internally by the inventory system when accessing groups through views.

§Parameters
  • group - A reference to the group to transform
  • options - Optional configuration data to pass to the transform function
§Returns

Returns a new Group instance with transformations applied. If no transform logic is defined for groups, returns a clone of the input group.

§Examples
struct GroupTransform;
impl Transform for GroupTransform {
    fn transform_group(&self, group: &Group, _options: Option<&TransformFunctionOptions>) -> Group {
        group.to_builder().port(443).build()
    }
}

let transform = TransformFunction::new_full(GroupTransform);
let group = Group::builder().platform("linux").build();
let transformed = transform.transform_group(&group, None);
assert_eq!(transformed.port(), Some(443));
Source

pub fn transform_defaults( &self, defaults: &Defaults, options: Option<&TransformFunctionOptions>, ) -> Defaults

Applies the transform function to inventory defaults.

This method delegates to the underlying Transform implementation to modify the provided defaults according to the transform logic. It’s primarily used internally by the inventory system when accessing defaults through Inventory::defaults().

§Parameters
  • defaults - A reference to the defaults to transform
  • options - Optional configuration data to pass to the transform function
§Returns

Returns a new Defaults instance with transformations applied. If no transform logic is defined for defaults, returns a clone of the input defaults.

§Examples
struct DefaultsTransform;
impl Transform for DefaultsTransform {
    fn transform_defaults(&self, defaults: &Defaults, _options: Option<&TransformFunctionOptions>) -> Defaults {
        defaults.to_builder().username("admin").build()
    }
}

let transform = TransformFunction::new_full(DefaultsTransform);
let defaults = Defaults::builder().port(22).build();
let transformed = transform.transform_defaults(&defaults, None);
assert_eq!(transformed.username(), Some("admin"));

Trait Implementations§

Source§

impl Clone for TransformFunction

Source§

fn clone(&self) -> TransformFunction

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TransformFunction

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.