1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//! Utility functions for output equality comparison in queries.
//!
//! These functions are designed to be used with the `#[query(output_eq = ...)]` attribute
//! when the output type is `Result<T, E>` and `E` does not implement `PartialEq`.
/// Compare only the `Ok` values. Returns `false` for any `Err` case,
/// causing downstream queries to be invalidated (recomputed).
///
/// # Example
/// ```
/// use query_flow::{query, Db, QueryError, QueryRuntime};
///
/// // Note: `MyError` deliberately has no `PartialEq`.
/// #[derive(Debug)]
/// struct MyError(String);
///
/// #[query(output_eq = query_flow::output_eq::ok_or_invalidate)]
/// fn my_query(db: &impl Db, succeed: bool) -> Result<Result<i32, MyError>, QueryError> {
/// let _ = db;
/// Ok(if succeed { Ok(1) } else { Err(MyError("boom".into())) })
/// }
///
/// let runtime = QueryRuntime::new();
/// assert!(matches!(*runtime.query(MyQuery::new(true)).unwrap(), Ok(1)));
/// assert!(matches!(*runtime.query(MyQuery::new(false)).unwrap(), Err(_)));
/// ```
/// Compare `Ok` values for equality, treat all `Err` as equal.
///
/// Use this when you want to suppress downstream recomputation if both results are errors,
/// regardless of the error content.
///
/// # Example
/// ```
/// use query_flow::{query, Db, QueryError, QueryRuntime};
///
/// // Note: `MyError` deliberately has no `PartialEq`.
/// #[derive(Debug)]
/// struct MyError(String);
///
/// #[query(output_eq = query_flow::output_eq::ignore_err)]
/// fn my_query(db: &impl Db, succeed: bool) -> Result<Result<i32, MyError>, QueryError> {
/// let _ = db;
/// Ok(if succeed { Ok(1) } else { Err(MyError("boom".into())) })
/// }
///
/// let runtime = QueryRuntime::new();
/// assert!(matches!(*runtime.query(MyQuery::new(false)).unwrap(), Err(_)));
/// ```