1use super::{Context, id};
2use std::fmt;
3
4#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash)]
6pub enum User {
7 Input(Input<id::AnyNode>),
8 Result(Result),
9}
10
11#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
13pub enum Origin {
14 Output(Output<id::AnyNode>),
15 Argument(Argument),
16}
17
18pub struct Input<K> {
20 pub node: id::Node<K>,
21 pub id: id::Input,
22}
23
24pub struct Output<K> {
26 pub node: id::Node<K>,
27 pub id: id::Output,
28}
29
30#[derive(Clone, Copy, PartialEq, Eq, Hash)]
32pub struct Argument {
33 pub region: id::Region,
34 pub id: id::Argument,
35}
36
37#[derive(Clone, Copy, PartialEq, Eq, Hash)]
39pub struct Result {
40 pub region: id::Region,
41 pub id: id::Result,
42}
43
44impl<K> Output<K> {
45 pub fn upcast(self) -> Output<id::AnyNode> {
46 Output {
47 node: id::Node::new(self.node.id),
48 id: self.id,
49 }
50 }
51}
52
53impl<K> Input<K> {
54 pub fn upcast(self) -> Input<id::AnyNode> {
55 Input {
56 node: id::Node::new(self.node.id),
57 id: self.id,
58 }
59 }
60}
61
62impl Context {
63 pub(crate) fn user_associated_node(&self, user: User) -> id::AnyNode {
64 match user {
65 User::Input(input) => input.node.id,
66 User::Result(result) => self.regions[result.region].container_node,
67 }
68 }
69 pub(crate) fn origin_associated_node(&self, origin: Origin) -> id::AnyNode {
70 match origin {
71 Origin::Output(output) => output.node.id,
72 Origin::Argument(argument) => self.regions[argument.region].container_node,
73 }
74 }
75
76 pub fn visit_nodes_upwards<T, F>(&self, user: impl Into<User>, f: &mut F) -> Option<T>
78 where
79 F: FnMut(&Self, id::AnyNode) -> Option<T>,
80 {
81 let user = user.into();
82 match user {
83 User::Input(input) => {
84 if let Some(t) = f(self, input.node.id) {
85 return Some(t);
86 }
87
88 let onode = self
89 .get_user(input)
90 .map(|origin| self.origin_associated_node(origin))?;
91
92 self.inputs(onode)
93 .map(User::from)
94 .find_map(|user| self.visit_nodes_upwards(user, f))
95 }
96 User::Result(result) => {
97 let node_id = self.regions[result.region].container_node;
98
99 if let Some(t) = f(self, node_id) {
100 return Some(t);
101 }
102
103 self.inputs(node_id)
104 .map(User::from)
105 .find_map(|user| self.visit_nodes_upwards(user, f))
106 }
107 }
108 }
109}
110
111impl<K> Clone for Input<K> {
112 fn clone(&self) -> Self {
113 *self
114 }
115}
116impl<K> Clone for Output<K> {
117 fn clone(&self) -> Self {
118 *self
119 }
120}
121
122impl<K> Copy for Input<K> {}
123impl<K> Copy for Output<K> {}
124
125impl<K> PartialEq for Output<K> {
126 fn eq(&self, other: &Self) -> bool {
127 self.node == other.node && self.id == other.id
128 }
129}
130impl<K> Eq for Output<K> {}
131
132impl<K> std::hash::Hash for Output<K> {
133 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
134 self.node.id.hash(state);
135 self.id.hash(state);
136 }
137}
138
139impl<K> PartialEq for Input<K> {
140 fn eq(&self, other: &Self) -> bool {
141 self.node == other.node && self.id == other.id
142 }
143}
144impl<K> Eq for Input<K> {}
145
146impl<K> std::hash::Hash for Input<K> {
147 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
148 self.node.id.hash(state);
149 self.id.hash(state);
150 }
151}
152
153impl<K> From<Input<K>> for User {
154 fn from(input: Input<K>) -> Self {
155 User::Input(input.upcast())
156 }
157}
158
159impl From<Result> for User {
160 fn from(result: Result) -> Self {
161 User::Result(result)
162 }
163}
164
165impl<K> From<Output<K>> for Origin {
166 fn from(output: Output<K>) -> Self {
167 Origin::Output(output.upcast())
168 }
169}
170
171impl From<Argument> for Origin {
172 fn from(argument: Argument) -> Self {
173 Origin::Argument(argument)
174 }
175}
176
177impl<K> fmt::Display for Input<K> {
178 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179 write!(f, "{}·{}", self.node.id, self.id)
180 }
181}
182
183impl<K> fmt::Display for Output<K> {
184 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
185 write!(f, "{}·{}", self.node.id, self.id)
186 }
187}
188
189impl fmt::Display for Argument {
190 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191 write!(f, "{}·{}", self.region, self.id)
192 }
193}
194
195impl fmt::Display for Result {
196 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
197 write!(f, "{}·{}", self.region, self.id)
198 }
199}
200
201impl<K> fmt::Debug for Input<K> {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 write!(f, "{}·{}", self.node.id, self.id)
204 }
205}
206
207impl<K> fmt::Debug for Output<K> {
208 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
209 write!(f, "{}·{}", self.node.id, self.id)
210 }
211}
212
213impl fmt::Debug for Argument {
214 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
215 write!(f, "{}·{}", self.region, self.id)
216 }
217}
218
219impl fmt::Debug for Result {
220 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
221 write!(f, "{}·{}", self.region, self.id)
222 }
223}
224
225impl fmt::Display for Origin {
226 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
227 match self {
228 Origin::Output(output) => output.fmt(f),
229 Origin::Argument(argument) => argument.fmt(f),
230 }
231 }
232}
233
234impl fmt::Display for User {
235 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
236 match self {
237 User::Input(input) => input.fmt(f),
238 User::Result(result) => result.fmt(f),
239 }
240 }
241}