#conditional #no-std #map-if #do-if #filter-if

no-std apply_if

Conditionally apply a closure to an item or return it

4 stable releases

Uses old Rust 2015

new 1.2.1 Oct 30, 2024
1.1.0 Jul 23, 2024
1.0.0 Dec 18, 2023

#510 in Development tools

Download history 1/week @ 2024-07-13 117/week @ 2024-07-20 25/week @ 2024-07-27 2/week @ 2024-09-21 1/week @ 2024-10-12 232/week @ 2024-10-26

233 downloads per month

MIT/Apache

15KB
172 lines

ApplyIf: Seamless Conditionals for Builder Chains

CI REUSE status

This crate provides the functions apply_if and apply_if_some for consuming builders, as well as apply_if_mut and apply_if_some_mut for mutable builder chains. They allow us to conditionally invoke builder functions while keeping the nice chaining syntax.

Examples

These examples use the derive_builder crate to create a builder and show how to use the apply_if... functions to conditionally invoke builder functions without breaking the chain.

Mutable Builders

This example uses a mutable builder pattern, which is why apply_if_mut and apply_if_some_mut are used.

extern crate derive_builder;
use derive_builder::Builder;
use apply_if::ApplyIf;

#[derive(Debug,PartialEq,Builder)]
struct Value{
  #[builder(default = 123)]
  first: i32,
  #[builder(default = 42.)]
  second: f32,
}

fn main () {
    // apply_if_mut only applies the function
    // if the condition is true
    let value = ValueBuilder::default()
        .apply_if_mut(true, |builder| builder.first(100))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 100, second: 1.337});

    let value = ValueBuilder::default()
        .apply_if_mut(false, |builder| builder.first(100))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 123, second: 1.337});

    // apply_if_some_mut only applies the function
    // if the optional contains a value
    
    let value = ValueBuilder::default()
        .apply_if_some_mut(Some(100), |builder,val| builder.first(val))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 100, second: 1.337});

    let value = ValueBuilder::default()
        .apply_if_some_mut(None, |builder,val| builder.first(val))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 123, second: 1.337});
}

Immutable Builders

This example uses a consuming builder pattern, which is why apply_if and apply_if_some are used.

extern crate derive_builder;
use derive_builder::Builder;
use apply_if::ApplyIf;

#[derive(Debug,PartialEq,Builder)]
#[builder(pattern = "immutable")]
struct Value{
  #[builder(default = 123)]
  first: i32,
  #[builder(default = 42.)]
  second: f32,
}

fn main () {
    // apply_if only applies the function
    // if the condition is true
    let value = ValueBuilder::default()
        .apply_if(true, |builder| builder.first(100))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 100, second: 1.337});

    let value = ValueBuilder::default()
        .apply_if(false, |builder| builder.first(100))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 123, second: 1.337});

    // apply_if_some only applies the function
    // if the optional contains a value
    let value = ValueBuilder::default()
        .apply_if_some(Some(100), |builder,val| builder.first(val))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 100, second: 1.337});

    let value = ValueBuilder::default()
        .apply_if_some(None, |builder,val| builder.first(val))
        .second(1.337)
        .build()
        .unwrap();
    assert_eq!(value, Value{first: 123, second: 1.337});
}

License

The code in this repository is licensed under either the MIT License or the Apache License 2.0, at your option. Documentation, specifically the documentation comments and all markdown files, are licensed under the Creative Commons ShareAlike 4.0 license. Generated files are provided under CC0-1.0.

No runtime deps