dear-imgui-rs 0.14.0

High-level Rust bindings to Dear ImGui v1.92.7 with docking, WGPU/GL backends, and extensions (ImPlot/ImPlot3D, ImNodes, ImGuizmo, file browser, reflection-based UI)
Documentation
use crate::internal::{DataType, DataTypeKind};
use crate::sys;

use super::SliderFlags;

pub(super) fn validate_slider_flags(caller: &str, flags: SliderFlags) {
    let bits = flags.bits();
    assert!(
        bits & (sys::ImGuiSliderFlags_WrapAround as i32) == 0,
        "{caller} does not support ImGuiSliderFlags_WrapAround; use DragFlags::WRAP_AROUND with drag widgets"
    );
    let unsupported = bits & !SliderFlags::all().bits();
    assert!(
        unsupported == 0,
        "{caller} received unsupported ImGuiSliderFlags bits: 0x{unsupported:X}"
    );
}

pub(super) fn validate_slider_range<Data: DataTypeKind>(caller: &str, min: &Data, max: &Data) {
    match Data::KIND {
        DataType::I8 | DataType::U8 | DataType::I16 | DataType::U16 => {}
        DataType::I32 => {
            let min = unsafe { *(min as *const Data as *const i32) };
            let max = unsafe { *(max as *const Data as *const i32) };
            let lower = i32::MIN / 2;
            let upper = i32::MAX / 2;
            assert!(
                (lower..=upper).contains(&min) && (lower..=upper).contains(&max),
                "{caller} i32/isize range endpoints must stay within i32::MIN/2..=i32::MAX/2"
            );
        }
        DataType::U32 => {
            let min = unsafe { *(min as *const Data as *const u32) };
            let max = unsafe { *(max as *const Data as *const u32) };
            let upper = u32::MAX / 2;
            assert!(
                min <= upper && max <= upper,
                "{caller} u32/usize range endpoints must be <= u32::MAX/2"
            );
        }
        DataType::I64 => {
            let min = unsafe { *(min as *const Data as *const i64) };
            let max = unsafe { *(max as *const Data as *const i64) };
            let lower = i64::MIN / 2;
            let upper = i64::MAX / 2;
            assert!(
                (lower..=upper).contains(&min) && (lower..=upper).contains(&max),
                "{caller} i64/isize range endpoints must stay within i64::MIN/2..=i64::MAX/2"
            );
        }
        DataType::U64 => {
            let min = unsafe { *(min as *const Data as *const u64) };
            let max = unsafe { *(max as *const Data as *const u64) };
            let upper = u64::MAX / 2;
            assert!(
                min <= upper && max <= upper,
                "{caller} u64/usize range endpoints must be <= u64::MAX/2"
            );
        }
        DataType::F32 => {
            let min = unsafe { *(min as *const Data as *const f32) };
            let max = unsafe { *(max as *const Data as *const f32) };
            assert!(
                min.is_finite()
                    && max.is_finite()
                    && (-f32::MAX / 2.0..=f32::MAX / 2.0).contains(&min)
                    && (-f32::MAX / 2.0..=f32::MAX / 2.0).contains(&max),
                "{caller} f32 range endpoints must be finite and stay within -f32::MAX/2..=f32::MAX/2"
            );
        }
        DataType::F64 => {
            let min = unsafe { *(min as *const Data as *const f64) };
            let max = unsafe { *(max as *const Data as *const f64) };
            assert!(
                min.is_finite()
                    && max.is_finite()
                    && (-f64::MAX / 2.0..=f64::MAX / 2.0).contains(&min)
                    && (-f64::MAX / 2.0..=f64::MAX / 2.0).contains(&max),
                "{caller} f64 range endpoints must be finite and stay within -f64::MAX/2..=f64::MAX/2"
            );
        }
    }
}

pub(super) fn validate_slider_preconditions<Data: DataTypeKind>(
    caller: &str,
    min: &Data,
    max: &Data,
    flags: SliderFlags,
) {
    validate_slider_flags(caller, flags);
    validate_slider_range(caller, min, max);
}