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
//! # cano-macros
//!
//! Procedural macros backing the [`cano`](https://docs.rs/cano) workflow engine.
//!
//! The crate exposes one attribute macro per `cano` core trait, all of which
//! perform the same async-fn-to-`Pin<Box<dyn Future + Send>>` rewrite that the
//! `async-trait` crate does. Splitting the macro by trait name (rather than a
//! single generic `async_trait`) gives a more self-documenting attribute at the
//! developer side: `#[cano::task]` on `impl Task` is immediately scannable for
//! what the impl is.
//!
//! Available macros:
//!
//! - [`task`] — for `impl Task` (and the `Task` trait definition itself)
//! - [`node`] — for `impl Node` and the `Node` trait
//! - [`resource`] — for `impl Resource` and the `Resource` trait
//!
//! All three are functionally identical; they differ only in name. New traits
//! that need async-fn-in-dyn rewriting can ship their own `cano-macros`
//! attribute alongside.
use TokenStream;
/// Derive a `from_resources(&Resources<_>) -> CanoResult<Self>` constructor that
/// pulls each field out of a `cano::Resources` map.
///
/// Each field must be `Arc<T>`. Use `#[res("key")]` for string-literal lookups
/// or `#[res(EnumType::Variant)]` for enum-path lookups. Use
/// `#[from_resources(key = MyType)]` on the struct to override the inferred key type.
///
/// # Example
///
/// ```ignore
/// use cano::prelude::*;
/// use std::sync::Arc;
///
/// #[derive(FromResources)]
/// struct Deps {
/// #[res("store")]
/// store: Arc<MemoryStore>,
/// }
/// ```
/// Apply to `impl Task for ...` blocks (or the `Task` trait definition itself).
///
/// Rewrites every `async fn` method into a method returning
/// `Pin<Box<dyn Future<Output = ...> + Send + 'async_trait>>`, the same shape
/// `async-trait` produces. This makes the methods callable through
/// `dyn Task<...>`.
///
/// Two surface forms are supported:
///
/// 1. **Trait-impl form (legacy):** `#[task] impl Task<S> for X { ... }` — user
/// writes the trait header.
/// 2. **Inherent-impl form:** `#[task(state = S [, key = K])] impl X { ... }` —
/// user writes only the inherent block; the macro builds the trait header
/// and enforces that exactly one of `run` / `run_bare` is present.
///
/// # Example
///
/// ```ignore
/// use cano::task;
///
/// #[task(state = MyState)]
/// impl MyTask {
/// async fn run_bare(&self) -> Result<TaskResult<MyState>, CanoError> {
/// Ok(TaskResult::Single(MyState::Done))
/// }
/// }
/// ```
/// Apply to `impl Node for ...` blocks, inherent `impl X { ... }` blocks, or
/// the `Node` trait definition itself.
///
/// Two surface forms are supported on impl blocks:
///
/// 1. **Trait-impl form (legacy):** `#[node] impl Node<S> for X { ... }`. The
/// macro infers `type PrepResult` / `type ExecResult` from the return types
/// of `prep` and `exec`, and supplies a default `fn config(&self) -> TaskConfig`
/// when missing.
/// 2. **Inherent-impl form:** `#[node(state = S [, key = K])] impl X { ... }`.
/// The macro builds the `impl Node<S [, K]> for X` header from the attribute
/// args, enforces that `prep` / `exec` / `post` are present, and injects
/// the same boilerplate as form 1.
///
/// On a trait definition (`#[node] pub trait Node ...`) the macro just performs
/// the async-fn-in-trait rewrite.
/// Apply to `impl Resource for ...` blocks (or the `Resource` trait definition itself).
///
/// Rewrites every `async fn` method into a method returning
/// `Pin<Box<dyn Future<Output = ...> + Send + 'async_trait>>`. Behaviorally
/// identical to [`task`] and [`node`]; the separate name makes the attribute
/// self-documenting at impl sites.
/// Derive an empty `cano::Resource` impl (uses the trait's default no-op
/// `setup` / `teardown`).
///
/// Apply this derive to any struct that needs to implement `Resource` but has no
/// custom lifecycle logic. The trait's `setup` and `teardown` defaults (which
/// return `Ok(())`) take effect automatically.
///
/// # Example
///
/// ```ignore
/// use cano::prelude::*;
///
/// #[derive(Resource)]
/// struct MyConfig {
/// timeout_ms: u64,
/// }
/// ```