godot_core/builtin/math/approx_eq.rs
1/*
2 * Copyright (c) godot-rust; Bromeon and contributors.
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 */
7
8// TODO(bromeon): test this against Godot's own is_equal_approx() implementation for equality-comparable built-in types (excl Callable/Rid/...)
9
10/// Approximate equality-comparison of geometric types.
11///
12/// The implementation is specific to the type. It's mostly used for gdext-internal tests, but you may use it for your own code.
13/// Note that we give no guarantees about precision, and implementation can change at any time.
14///
15/// We currently also do not guarantee that this gives the same results as Godot's own `is_equal_approx()` function; although this may
16/// be the goal in the future.
17pub trait ApproxEq: PartialEq {
18 fn approx_eq(&self, other: &Self) -> bool;
19}
20
21/// Asserts that two values are approximately equal
22///
23/// For comparison, this uses `ApproxEq::approx_eq` by default, or the provided `fn = ...` function.
24#[macro_export]
25macro_rules! assert_eq_approx {
26 ($actual:expr, $expected:expr, fn = $func:expr $(,)?) => {
27 match ($actual, $expected) {
28 (a, b) => assert!(($func)(&a, &b), "\n left: {:?},\n right: {:?}", $actual, $expected)
29 }
30 };
31 ($actual:expr, $expected:expr, fn = $func:expr, $($t:tt)+) => {
32 match ($actual, $expected) {
33 (a, b) => assert!(($func)(&a, &b), "\n left: {:?},\n right: {:?}{}", $actual, $expected, format_args!($($t)+) )
34 }
35 };
36 ($actual:expr, $expected:expr $(,)?) => {
37 match ($actual, $expected) {
38 (a, b) => assert!($crate::builtin::math::ApproxEq::approx_eq(&a, &b), "\n left: {:?},\n right: {:?}", $actual, $expected),
39 // (a, b) => $crate::assert_eq_approx!($actual, $expected, fn = $crate::builtin::ApproxEq::approx_eq),
40 }
41 };
42 ($actual:expr, $expected:expr, $($t:tt)+) => {
43 match ($actual, $expected) {
44 (a, b) => assert!($crate::builtin::math::ApproxEq::approx_eq(&a, &b), "\n left: {:?},\n right: {:?},\n{}", $actual, $expected, format_args!($($t)+)),
45 // (a, b) => $crate::assert_eq_approx!($actual, $expected, fn = $crate::builtin::ApproxEq::approx_eq, $($t)+),
46 }
47 };
48}
49
50/// Asserts that two values are not approximately equal, using the provided
51/// `func` for equality checking.
52#[macro_export]
53macro_rules! assert_ne_approx {
54 ($actual:expr, $expected:expr, fn = $func:expr $(, $($t:tt)* )?) => {
55 #[allow(clippy::redundant_closure_call)]
56 {
57 $crate::assert_eq_approx!($actual, $expected, fn = |a,b| !($func)(a, b) $(, $($t)* )?)
58 }
59 };
60
61 ($actual:expr, $expected:expr $(, $($t:tt)* )?) => {
62 #[allow(clippy::redundant_closure_call)]
63 {
64 $crate::assert_eq_approx!($actual, $expected, fn = |a, b| !$crate::builtin::math::ApproxEq::approx_eq(a, b) $(, $($t)* )?)
65 }
66 };
67}