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:
-
Host-only transform - Using
new(), which accepts a closure that only transforms hosts. Groups and defaults pass through unchanged. -
Full transform - Using
new_full(), which accepts a type implementing theTransformtrait, allowing custom transformation of hosts, groups, and defaults.
§When Transforms Are Applied
Transforms are applied lazily when accessing inventory entities through:
Inventory::hosts()- Returns aHostsViewthat applies transforms on accessInventory::groups()- Returns aGroupsViewthat applies transforms on accessInventory::defaults()- Returns transformed defaultsInventory::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 logicImplementations§
Source§impl TransformFunction
impl TransformFunction
Sourcepub fn new<F>(func: F) -> Self
pub fn new<F>(func: F) -> Self
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 aHost. The closure must beSend + Sync + 'staticto 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 transformedOption<&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()
});Sourcepub fn new_full<T>(transform: T) -> Selfwhere
T: Transform + 'static,
pub fn new_full<T>(transform: T) -> Selfwhere
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 theTransformtrait. The type must be'staticto allow it to be stored in theArcwrapper.
§Parameters
transform- An instance of a type implementingTransform. The instance will be wrapped in anArcfor 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(),
});Sourcepub fn transform_host(
&self,
host: &Host,
options: Option<&TransformFunctionOptions>,
) -> Host
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 transformoptions- 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));Sourcepub fn transform_group(
&self,
group: &Group,
options: Option<&TransformFunctionOptions>,
) -> Group
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 transformoptions- 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));Sourcepub fn transform_defaults(
&self,
defaults: &Defaults,
options: Option<&TransformFunctionOptions>,
) -> Defaults
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 transformoptions- 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
impl Clone for TransformFunction
Source§fn clone(&self) -> TransformFunction
fn clone(&self) -> TransformFunction
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more