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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
//! Procedural macros for query-flow.
//!
//! This crate provides attribute macros for defining queries, asset keys,
//! and asset locators with minimal boilerplate.
//!
//! # Query Example
//!
//! ```ignore
//! use query_flow::{query, Db, QueryError};
//!
//! #[query]
//! pub fn add(db: &impl Db, a: i32, b: i32) -> Result<i32, QueryError> {
//! Ok(a + b)
//! }
//!
//! // Generates:
//! // pub struct Add { pub a: i32, pub b: i32 }
//! // impl Query for Add { ... }
//! ```
//!
//! # Asset Key Example
//!
//! ```ignore
//! use query_flow::asset_key;
//!
//! #[asset_key(asset = String)]
//! pub struct ConfigFile(pub PathBuf);
//!
//! // Generates:
//! // impl AssetKey for ConfigFile { type Asset = String; ... }
//! ```
//!
//! # Asset Locator Example
//!
//! ```ignore
//! use query_flow::{asset_locator, Db, LocateResult, QueryError};
//!
//! #[asset_locator]
//! fn pending(_db: &impl Db, _key: &ConfigFile) -> Result<LocateResult<String>, QueryError> {
//! Ok(LocateResult::Pending)
//! }
//!
//! // Generates:
//! // struct Pending;
//! // impl AssetLocator<ConfigFile> for Pending { ... }
//! ```
use ;
use TokenStream;
use ;
use crate::;
/// Define a query from a function.
///
/// # Attributes
///
/// - `output_eq = path`: Custom equality function (default: PartialEq)
/// - `keys(a, b, ...)`: Specify which params form the cache key
/// - `name = "Name"`: Override generated struct name
///
/// # Example
///
/// ```ignore
/// use query_flow::{query, Db, QueryError};
///
/// // Basic query - all params are keys
/// #[query]
/// fn add(db: &impl Db, a: i32, b: i32) -> Result<i32, QueryError> {
/// Ok(a + b)
/// }
///
/// // With options
/// #[query(keys(id))]
/// pub fn fetch_user(db: &impl Db, id: u64, include_deleted: bool) -> Result<User, QueryError> {
/// // include_deleted is NOT part of the cache key
/// Ok(load_user(id, include_deleted))
/// }
/// ```
/// Define an asset key type.
///
/// # Attributes
///
/// - `asset = Type`: The asset type this key loads (required)
/// - `asset_eq`: Use PartialEq for asset comparison (default)
/// - `asset_eq = path`: Use custom function for asset comparison
///
/// Durability is specified when calling `resolve_asset()`, not on the type.
///
/// # Example
///
/// ```ignore
/// use query_flow::{asset_key, DurabilityLevel};
/// use std::path::PathBuf;
///
/// #[asset_key(asset = String)]
/// pub struct ConfigFile(pub PathBuf);
///
/// // Custom equality
/// #[asset_key(asset = ImageData, asset_eq = image_bytes_eq)]
/// pub struct TexturePath(pub String);
///
/// // When resolving:
/// runtime.resolve_asset(ConfigFile(path), content, DurabilityLevel::Volatile);
/// ```
/// Define an asset locator from a function.
///
/// This macro generates a struct and `AssetLocator` implementation from a
/// locator function, making it easier to define inline locators in tests.
///
/// The function name is converted to PascalCase for the struct name.
/// The `db` parameter name can be anything (commonly `_db` if unused).
/// The key type is inferred from the second parameter.
///
/// # Example
///
/// ```ignore
/// use query_flow::{asset_locator, Db, LocateResult, QueryError};
///
/// // Basic locator - returns Pending
/// #[asset_locator]
/// fn pending(_db: &impl Db, _key: &ConfigFile) -> Result<LocateResult<String>, QueryError> {
/// Ok(LocateResult::Pending)
/// }
///
/// // Generates:
/// // struct Pending;
/// // impl AssetLocator<ConfigFile> for Pending { ... }
///
/// // Use it:
/// runtime.register_asset_locator(Pending);
/// ```