Module mutating_function_once

Module mutating_function_once 

Source
Expand description

§MutatingFunctionOnce Types

Provides Java-like one-time MutatingFunction interface implementations for performing operations that consume self, accept a mutable reference, and return a result.

It is similar to the FnOnce(&mut T) -> R trait in the standard library.

This module provides a unified MutatingFunctionOnce trait and a Box-based single ownership implementation:

  • BoxMutatingFunctionOnce<T, R>: Box-based single ownership implementation for one-time use scenarios

§Design Philosophy

The key difference between MutatingFunctionOnce and MutatingFunction:

  • MutatingFunction: &self, can be called multiple times, uses Fn(&mut T) -> R
  • MutatingFunctionOnce: self, can only be called once, uses FnOnce(&mut T) -> R

§MutatingFunctionOnce vs MutatingFunction

FeatureMutatingFunctionMutatingFunctionOnce
Self Parameter&selfself
Call CountMultipleOnce
Closure TypeFn(&mut T) -> RFnOnce(&mut T) -> R
Use CasesRepeatable operationsOne-time resource
transfers

§Why MutatingFunctionOnce?

Core value of MutatingFunctionOnce:

  1. Store FnOnce closures: Allows moving captured variables
  2. Delayed execution: Store in data structures, execute later
  3. Resource transfer: Suitable for scenarios requiring ownership transfer
  4. Return results: Unlike MutatorOnce, returns information about the operation

§Why Only Box Variant?

  • Arc/Rc conflicts with FnOnce semantics: FnOnce can only be called once, while shared ownership implies multiple references
  • Box is perfect match: Single ownership aligns perfectly with one-time call semantics

§Use Cases

§BoxMutatingFunctionOnce

  • Post-initialization callbacks (moving data, returning status)
  • Resource transfer with result (moving Vec, returning old value)
  • One-time complex operations (requiring moved capture variables)
  • Validation with fixes (fix data once, return validation result)

§Examples

§Basic Usage

use prism3_function::{BoxMutatingFunctionOnce, MutatingFunctionOnce};

let data = vec![1, 2, 3];
let func = BoxMutatingFunctionOnce::new(move |x: &mut Vec<i32>| {
    let old_len = x.len();
    x.extend(data); // Move data
    old_len
});

let mut target = vec![0];
let old_len = func.apply(&mut target);
assert_eq!(old_len, 1);
assert_eq!(target, vec![0, 1, 2, 3]);

§Method Chaining

use prism3_function::{BoxMutatingFunctionOnce, MutatingFunctionOnce};

let data1 = vec![1, 2];
let data2 = vec![3, 4];

let chained = BoxMutatingFunctionOnce::new(move |x: &mut Vec<i32>| {
    x.extend(data1);
    x.len()
})
.and_then(move |x: &mut Vec<i32>| {
    x.extend(data2);
    x.len()
});

let mut target = vec![0];
let final_len = chained.apply(&mut target);
assert_eq!(final_len, 5);
assert_eq!(target, vec![0, 1, 2, 3, 4]);

§Validation Pattern

use prism3_function::{BoxMutatingFunctionOnce, MutatingFunctionOnce};

struct Data {
    value: i32,
}

let validator = BoxMutatingFunctionOnce::new(|data: &mut Data| {
    if data.value < 0 {
        data.value = 0;
        Err("Fixed negative value")
    } else {
        Ok("Valid")
    }
});

let mut data = Data { value: -5 };
let result = validator.apply(&mut data);
assert_eq!(data.value, 0);
assert!(result.is_err());

§Author

Haixing Hu

Structs§

BoxConditionalMutatingFunctionOnce
BoxConditionalMutatingFunctionOnce struct
BoxMutatingFunctionOnce
BoxMutatingFunctionOnce struct

Traits§

FnMutatingFunctionOnceOps
Extension trait for closures implementing the base function trait
MutatingFunctionOnce
MutatingFunctionOnce trait - One-time mutating function interface