structupdate_support 0.4.1

Type definitions used by the structupdate crate
Documentation
//! Helper functions for creating [`Value`] instances with custom defaults.
//!
//! These functions are useful with the `#[structupdate(init_with = ...)]` attribute
//! to specify non-standard default values for fields.
//!
//! # Example
//!
//! ```rust
//! use structupdate::{structupdate, Value, Node};
//! use structupdate::defaults::{value_true, default_u32};
//!
//! // Use the default helpers to create Value instances with custom defaults
//! let enabled = value_true();
//! assert_eq!(*enabled.value(), true);
//!
//! let timeout = default_u32(30)();
//! assert_eq!(*timeout.value(), 30);
//!
//! // For init_with, define a function returning the raw value
//! fn default_timeout() -> u32 { 30 }
//!
//! #[structupdate]
//! #[derive(Default, Clone, PartialEq)]
//! pub struct Config {
//!     #[structupdate(init_with = default_timeout)]
//!     pub timeout: Value<u32>,
//! }
//! ```

use crate::DefaultValueConstructor;
use crate::Value;

/// Creates a [`Value<bool>`] with a default of `false`.
///
/// This is equivalent to `Value::default()` for booleans.
pub fn value_false() -> Value<bool> {
    Value::default()
}

/// Creates a [`Value<bool>`] with a default of `true`.
pub fn value_true() -> Value<bool> {
    default_value(|| true)
}

/// Returns a closure that creates a [`Value<String>`] with the given default.
///
/// # Example
///
/// ```rust
/// use structupdate::defaults::default_string;
///
/// let make_greeting = default_string("Hello");
/// let value = make_greeting();
/// assert_eq!(value.value(), &"Hello".to_string());
/// ```
pub fn default_string(s: impl ToString + Clone + 'static) -> impl Fn() -> Value<String> {
    move || {
        let s_clone = s.clone();
        default_value(|| s_clone.to_string())
    }
}

macro_rules! make_default_fn {
    ($name:ident, $ty:ty, $doc:expr) => {
        #[doc = $doc]
        pub fn $name(int: $ty) -> impl Fn() -> Value<$ty> {
            move || default_value(|| int)
        }
    };
}

make_default_fn!(
    default_u8,
    u8,
    "Returns a closure that creates a [`Value<u8>`] with the given default."
);
make_default_fn!(
    default_u16,
    u16,
    "Returns a closure that creates a [`Value<u16>`] with the given default."
);
make_default_fn!(
    default_u32,
    u32,
    "Returns a closure that creates a [`Value<u32>`] with the given default."
);
make_default_fn!(
    default_u64,
    u64,
    "Returns a closure that creates a [`Value<u64>`] with the given default."
);
make_default_fn!(
    default_i8,
    i8,
    "Returns a closure that creates a [`Value<i8>`] with the given default."
);
make_default_fn!(
    default_i16,
    i16,
    "Returns a closure that creates a [`Value<i16>`] with the given default."
);
make_default_fn!(
    default_i32,
    i32,
    "Returns a closure that creates a [`Value<i32>`] with the given default."
);
make_default_fn!(
    default_i64,
    i64,
    "Returns a closure that creates a [`Value<i64>`] with the given default."
);

/// Creates a [`Value<T>`] with a custom default value.
///
/// The provided closure `f` is called twice: once to set the initial value,
/// and once to store the default for later use with `SetToDefault`.
///
/// # Example
///
/// ```rust
/// use structupdate::defaults::default_value;
///
/// let value = default_value(|| vec![1, 2, 3]);
/// assert_eq!(value.value(), &vec![1, 2, 3]);
/// ```
pub fn default_value<F, T>(f: F) -> Value<T>
where
    F: Fn() -> T,
{
    Value {
        value: f(),
        default: DefaultValueConstructor::Custom(f()),
    }
}