1mod util;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::{DeriveInput, parse_macro_input};
6
7#[proc_macro_derive(GraphBase, attributes(graph, gryf_crate))]
8pub fn graph_base(tokens: TokenStream) -> TokenStream {
9 let input = parse_macro_input!(tokens as DeriveInput);
10
11 let gryf = util::get_gryf_path(&input);
12
13 let name = &input.ident;
14 let field = util::get_graph_field(&input);
15
16 let field_name = field.ident.as_ref().unwrap();
17 let field_type = &field.ty;
18
19 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
20 let where_clause = util::augment_where_clause(
21 where_clause,
22 vec![(field_type.clone(), quote! { #gryf::core::GraphBase })],
23 );
24
25 let implemented = quote! {
26 impl #impl_generics #gryf::core::GraphBase for #name #ty_generics #where_clause {
27 type VertexId = <#field_type as #gryf::core::GraphBase>::VertexId;
28 type EdgeId = <#field_type as #gryf::core::GraphBase>::EdgeId;
29 type EdgeType = <#field_type as #gryf::core::GraphBase>::EdgeType;
30
31 fn vertex_count_hint(&self) -> Option<usize> {
32 <#field_type as #gryf::core::GraphBase>::vertex_count_hint(&self.#field_name)
33 }
34
35 fn edge_count_hint(&self) -> Option<usize> {
36 <#field_type as #gryf::core::GraphBase>::edge_count_hint(&self.#field_name)
37 }
38 }
39 };
40
41 TokenStream::from(implemented)
42}
43
44#[proc_macro_derive(Neighbors, attributes(graph, gryf_crate))]
45pub fn neighbors(tokens: TokenStream) -> TokenStream {
46 let input = parse_macro_input!(tokens as DeriveInput);
47
48 let gryf = util::get_gryf_path(&input);
49
50 let name = &input.ident;
51 let field = util::get_graph_field(&input);
52
53 let field_name = field.ident.as_ref().unwrap();
54 let field_type = &field.ty;
55
56 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
57 let where_clause = util::augment_where_clause(
58 where_clause,
59 vec![(field_type.clone(), quote! { #gryf::core::Neighbors })],
60 );
61
62 let implemented = quote! {
63 impl #impl_generics #gryf::core::Neighbors for #name #ty_generics #where_clause {
64 type NeighborRef<'a> = <#field_type as #gryf::core::Neighbors>::NeighborRef<'a>
65 where
66 Self: 'a;
67
68 type NeighborsIter<'a> = <#field_type as #gryf::core::Neighbors>::NeighborsIter<'a>
69 where
70 Self: 'a;
71
72 fn neighbors_undirected(&self, from: &Self::VertexId) -> Self::NeighborsIter<'_> {
73 <#field_type as #gryf::core::Neighbors>::neighbors_undirected(&self.#field_name, from)
74 }
75
76 fn neighbors_directed(&self, from: &Self::VertexId, dir: #gryf::core::marker::Direction) -> Self::NeighborsIter<'_> {
77 <#field_type as #gryf::core::Neighbors>::neighbors_directed(&self.#field_name, from, dir)
78 }
79
80 fn degree_undirected(&self, id: &Self::VertexId) -> usize {
81 <#field_type as #gryf::core::Neighbors>::degree_undirected(&self.#field_name, id)
82 }
83
84 fn degree_directed(&self, id: &Self::VertexId, dir: #gryf::core::marker::Direction) -> usize {
85 <#field_type as #gryf::core::Neighbors>::degree_directed(&self.#field_name, id, dir)
86 }
87 }
88 };
89
90 TokenStream::from(implemented)
91}
92
93#[proc_macro_derive(VertexSet, attributes(graph, gryf_crate))]
94pub fn vertex_set(tokens: TokenStream) -> TokenStream {
95 let input = parse_macro_input!(tokens as DeriveInput);
96
97 let gryf = util::get_gryf_path(&input);
98
99 let name = &input.ident;
100 let field = util::get_graph_field(&input);
101
102 let field_name = field.ident.as_ref().unwrap();
103 let field_type = &field.ty;
104
105 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
106 let where_clause = util::augment_where_clause(
107 where_clause,
108 vec![(field_type.clone(), quote! { #gryf::core::VertexSet })],
109 );
110
111 let implemented = quote! {
112 impl #impl_generics #gryf::core::VertexSet for #name #ty_generics #where_clause {
113 type VerticesByIdIter<'a> = <#field_type as #gryf::core::VertexSet>::VerticesByIdIter<'a>
114 where
115 Self: 'a;
116
117 fn vertices_by_id(&self) -> Self::VerticesByIdIter<'_> {
118 <#field_type as #gryf::core::VertexSet>::vertices_by_id(&self.#field_name)
119 }
120
121 fn vertex_count(&self) -> usize {
122 <#field_type as #gryf::core::VertexSet>::vertex_count(&self.#field_name)
123 }
124
125 fn vertex_bound(&self) -> usize
126 where
127 Self::VertexId: #gryf::core::id::IntegerIdType,
128 {
129 <#field_type as #gryf::core::VertexSet>::vertex_bound(&self.#field_name)
130 }
131
132 fn contains_vertex(&self, id: &Self::VertexId) -> bool {
133 <#field_type as #gryf::core::VertexSet>::contains_vertex(&self.#field_name, id)
134 }
135
136 fn vertex_id_map(&self) -> #gryf::core::id::CompactIdMap<Self::VertexId> {
137 <#field_type as #gryf::core::VertexSet>::vertex_id_map(&self.#field_name)
138 }
139 }
140 };
141
142 TokenStream::from(implemented)
143}
144
145#[proc_macro_derive(EdgeSet, attributes(graph, gryf_crate))]
146pub fn edge_set(tokens: TokenStream) -> TokenStream {
147 let input = parse_macro_input!(tokens as DeriveInput);
148
149 let gryf = util::get_gryf_path(&input);
150
151 let name = &input.ident;
152 let field = util::get_graph_field(&input);
153
154 let field_name = field.ident.as_ref().unwrap();
155 let field_type = &field.ty;
156
157 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
158 let where_clause = util::augment_where_clause(
159 where_clause,
160 vec![(field_type.clone(), quote! { #gryf::core::EdgeSet })],
161 );
162
163 let implemented = quote! {
164 impl #impl_generics #gryf::core::EdgeSet for #name #ty_generics #where_clause {
165 type EdgesByIdIter<'a> = <#field_type as #gryf::core::EdgeSet>::EdgesByIdIter<'a>
166 where
167 Self: 'a;
168
169 type EdgeIdIter<'a> = <#field_type as #gryf::core::EdgeSet>::EdgeIdIter<'a>
170 where
171 Self: 'a;
172
173 fn edges_by_id(&self) -> Self::EdgesByIdIter<'_> {
174 <#field_type as #gryf::core::EdgeSet>::edges_by_id(&self.#field_name)
175 }
176
177 fn edge_id(&self, from: &Self::VertexId, to: &Self::VertexId) -> Self::EdgeIdIter<'_> {
178 <#field_type as #gryf::core::EdgeSet>::edge_id(&self.#field_name, from, to)
179 }
180
181 fn endpoints(&self, id: &Self::EdgeId) -> Option<(Self::VertexId, Self::VertexId)> {
182 <#field_type as #gryf::core::EdgeSet>::endpoints(&self.#field_name, id)
183 }
184
185 fn edge_count(&self) -> usize {
186 <#field_type as #gryf::core::EdgeSet>::edge_count(&self.#field_name)
187 }
188
189 fn edge_bound(&self) -> usize
190 where
191 Self::EdgeId: #gryf::core::id::IntegerIdType,
192 {
193 <#field_type as #gryf::core::EdgeSet>::edge_bound(&self.#field_name)
194 }
195
196 fn contains_edge(&self, id: &Self::EdgeId) -> bool {
197 <#field_type as #gryf::core::EdgeSet>::contains_edge(&self.#field_name, id)
198 }
199
200 fn contains_edge_between(&self, from: &Self::VertexId, to: &Self::VertexId) -> bool {
201 <#field_type as #gryf::core::EdgeSet>::contains_edge_between(&self.#field_name, from, to)
202 }
203
204 fn edge_id_any(&self, from: &Self::VertexId, to: &Self::VertexId) -> Option<Self::EdgeId> {
205 <#field_type as #gryf::core::EdgeSet>::edge_id_any(&self.#field_name, from, to)
206 }
207
208 fn edge_id_map(&self) -> #gryf::core::id::CompactIdMap<Self::EdgeId> {
209 <#field_type as #gryf::core::EdgeSet>::edge_id_map(&self.#field_name)
210 }
211 }
212 };
213
214 TokenStream::from(implemented)
215}
216
217#[proc_macro_derive(GraphRef, attributes(graph, gryf_crate))]
218pub fn graph_ref(tokens: TokenStream) -> TokenStream {
219 let input = parse_macro_input!(tokens as DeriveInput);
220
221 let gryf = util::get_gryf_path(&input);
222
223 let name = &input.ident;
224 let field = util::get_graph_field(&input);
225
226 let field_name = field.ident.as_ref().unwrap();
227 let field_type = &field.ty;
228
229 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
230 let impl_generics = util::augment_impl_generics_if_necessary(impl_generics, vec!["V", "E"]);
231 let where_clause = util::augment_where_clause(
232 where_clause,
233 vec![(field_type.clone(), quote! { #gryf::core::GraphRef<V, E> })],
234 );
235
236 let implemented = quote! {
237 impl #impl_generics #gryf::core::GraphRef<V, E> for #name #ty_generics #where_clause {
238 type VertexRef<'a> = <#field_type as #gryf::core::GraphRef<V, E>>::VertexRef<'a>
239 where
240 Self: 'a,
241 V: 'a;
242
243 type VerticesIter<'a> = <#field_type as #gryf::core::GraphRef<V, E>>::VerticesIter<'a>
244 where
245 Self: 'a,
246 V: 'a;
247
248 type EdgeRef<'a> = <#field_type as #gryf::core::GraphRef<V, E>>::EdgeRef<'a>
249 where
250 Self: 'a,
251 E: 'a;
252
253 type EdgesIter<'a> = <#field_type as #gryf::core::GraphRef<V, E>>::EdgesIter<'a>
254 where
255 Self: 'a,
256 E: 'a;
257
258 fn vertices(&self) -> Self::VerticesIter<'_> {
259 <#field_type as #gryf::core::GraphRef<V, E>>::vertices(&self.#field_name)
260 }
261
262 fn edges(&self) -> Self::EdgesIter<'_> {
263 <#field_type as #gryf::core::GraphRef<V, E>>::edges(&self.#field_name)
264 }
265
266 fn vertex(&self, id: &Self::VertexId) -> Option<&V> {
267 <#field_type as #gryf::core::GraphRef<V, E>>::vertex(&self.#field_name, id)
268 }
269
270 fn edge(&self, id: &Self::EdgeId) -> Option<&E> {
271 <#field_type as #gryf::core::GraphRef<V, E>>::edge(&self.#field_name, id)
272 }
273
274 fn find_vertex(&self, vertex: &V) -> Option<Self::VertexId>
275 where
276 V: Eq,
277 {
278 <#field_type as #gryf::core::GraphRef<V, E>>::find_vertex(&self.#field_name, vertex)
279 }
280 }
281 };
282
283 TokenStream::from(implemented)
284}
285
286#[proc_macro_derive(GraphMut, attributes(graph, gryf_crate))]
287pub fn graph_mut(tokens: TokenStream) -> TokenStream {
288 let input = parse_macro_input!(tokens as DeriveInput);
289
290 let gryf = util::get_gryf_path(&input);
291
292 let name = &input.ident;
293 let field = util::get_graph_field(&input);
294
295 let field_name = field.ident.as_ref().unwrap();
296 let field_type = &field.ty;
297
298 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
299 let impl_generics = util::augment_impl_generics_if_necessary(impl_generics, vec!["V", "E"]);
300 let where_clause = util::augment_where_clause(
301 where_clause,
302 vec![(field_type.clone(), quote! { #gryf::core::GraphMut<V, E> })],
303 );
304
305 let implemented = quote! {
306 impl #impl_generics #gryf::core::GraphMut<V, E> for #name #ty_generics #where_clause {
307 fn vertex_mut(&mut self, id: &Self::VertexId) -> Option<&mut V> {
308 <#field_type as #gryf::core::GraphMut<V, E>>::vertex_mut(&mut self.#field_name, id)
309 }
310
311 fn edge_mut(&mut self, id: &Self::EdgeId) -> Option<&mut E> {
312 <#field_type as #gryf::core::GraphMut<V, E>>::edge_mut(&mut self.#field_name, id)
313 }
314
315 fn try_replace_vertex(
316 &mut self,
317 id: &Self::VertexId,
318 vertex: V,
319 ) -> Result<V, #gryf::core::error::ReplaceVertexError<V>> {
320 <#field_type as #gryf::core::GraphMut<V, E>>::try_replace_vertex(&mut self.#field_name, id, vertex)
321 }
322
323 fn replace_vertex(&mut self, id: &Self::VertexId, vertex: V) -> V {
324 <#field_type as #gryf::core::GraphMut<V, E>>::replace_vertex(&mut self.#field_name, id, vertex)
325 }
326
327 fn try_replace_edge(&mut self, id: &Self::EdgeId, edge: E) -> Result<E, #gryf::core::error::ReplaceEdgeError<E>> {
328 <#field_type as #gryf::core::GraphMut<V, E>>::try_replace_edge(&mut self.#field_name, id, edge)
329 }
330
331 fn replace_edge(&mut self, id: &Self::EdgeId, edge: E) -> E {
332 <#field_type as #gryf::core::GraphMut<V, E>>::replace_edge(&mut self.#field_name, id, edge)
333 }
334 }
335 };
336
337 TokenStream::from(implemented)
338}
339
340#[proc_macro_derive(GraphAdd, attributes(graph, gryf_crate))]
341pub fn graph_add(tokens: TokenStream) -> TokenStream {
342 let input = parse_macro_input!(tokens as DeriveInput);
343
344 let gryf = util::get_gryf_path(&input);
345
346 let name = &input.ident;
347 let field = util::get_graph_field(&input);
348
349 let field_name = field.ident.as_ref().unwrap();
350 let field_type = &field.ty;
351
352 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
353 let impl_generics = util::augment_impl_generics_if_necessary(impl_generics, vec!["V", "E"]);
354 let where_clause = util::augment_where_clause(
355 where_clause,
356 vec![(field_type.clone(), quote! { #gryf::core::GraphAdd<V, E> })],
357 );
358
359 let implemented = quote! {
360 impl #impl_generics #gryf::core::GraphAdd<V, E> for #name #ty_generics #where_clause {
361 fn try_add_vertex(&mut self, vertex: V) -> Result<Self::VertexId, #gryf::core::error::AddVertexError<V>> {
362 <#field_type as #gryf::core::GraphAdd<V, E>>::try_add_vertex(&mut self.#field_name, vertex)
363 }
364
365 fn try_add_edge(
366 &mut self,
367 from: &Self::VertexId,
368 to: &Self::VertexId,
369 edge: E,
370 ) -> Result<Self::EdgeId, #gryf::core::error::AddEdgeError<E>> {
371 <#field_type as #gryf::core::GraphAdd<V, E>>::try_add_edge(&mut self.#field_name, from, to, edge)
372 }
373
374 fn add_vertex(&mut self, vertex: V) -> Self::VertexId {
375 <#field_type as #gryf::core::GraphAdd<V, E>>::add_vertex(&mut self.#field_name, vertex)
376 }
377
378 fn try_get_or_add_vertex(&mut self, vertex: V) -> Result<Self::VertexId, #gryf::core::error::AddVertexError<V>>
379 where
380 V: Eq,
381 {
382 <#field_type as #gryf::core::GraphAdd<V, E>>::try_get_or_add_vertex(&mut self.#field_name, vertex)
383 }
384
385 fn get_or_add_vertex(&mut self, vertex: V) -> Self::VertexId
386 where
387 V: Eq,
388 {
389 <#field_type as #gryf::core::GraphAdd<V, E>>::get_or_add_vertex(&mut self.#field_name, vertex)
390 }
391
392 fn add_edge(&mut self, from: &Self::VertexId, to: &Self::VertexId, edge: E) -> Self::EdgeId {
393 <#field_type as #gryf::core::GraphAdd<V, E>>::add_edge(&mut self.#field_name, from, to, edge)
394 }
395
396 fn try_add_edge_connecting(
397 &mut self,
398 from: V,
399 to: V,
400 edge: E,
401 ) -> Result<Self::EdgeId, #gryf::core::error::AddEdgeConnectingError<V, E>>
402 where
403 V: Eq,
404 {
405 <#field_type as #gryf::core::GraphAdd<V, E>>::try_add_edge_connecting(&mut self.#field_name, from, to, edge)
406 }
407
408 fn add_edge_connecting(&mut self, from: V, to: V, edge: E) -> Self::EdgeId
409 where
410 V: Eq,
411 {
412 <#field_type as #gryf::core::GraphAdd<V, E>>::add_edge_connecting(&mut self.#field_name, from, to, edge)
413 }
414 }
415 };
416
417 TokenStream::from(implemented)
418}
419
420#[proc_macro_derive(GraphFull, attributes(graph, gryf_crate))]
421pub fn graph_full(tokens: TokenStream) -> TokenStream {
422 let input = parse_macro_input!(tokens as DeriveInput);
423
424 let gryf = util::get_gryf_path(&input);
425
426 let name = &input.ident;
427 let field = util::get_graph_field(&input);
428
429 let field_name = field.ident.as_ref().unwrap();
430 let field_type = &field.ty;
431
432 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
433 let impl_generics = util::augment_impl_generics_if_necessary(impl_generics, vec!["V", "E"]);
434 let where_clause = util::augment_where_clause(
435 where_clause,
436 vec![(field_type.clone(), quote! { #gryf::core::GraphFull<V, E> })],
437 );
438
439 let implemented = quote! {
440 impl #impl_generics #gryf::core::GraphFull<V, E> for #name #ty_generics #where_clause {
441 fn remove_vertex(&mut self, id: &Self::VertexId) -> Option<V> {
442 <#field_type as #gryf::core::GraphFull<V, E>>::remove_vertex(&mut self.#field_name, id)
443 }
444
445 fn remove_edge(&mut self, id: &Self::EdgeId) -> Option<E> {
446 <#field_type as #gryf::core::GraphFull<V, E>>::remove_edge(&mut self.#field_name, id)
447 }
448
449 fn clear(&mut self) {
450 <#field_type as #gryf::core::GraphFull<V, E>>::clear(&mut self.#field_name)
451 }
452
453 fn remove_edges_between(&mut self, from: &Self::VertexId, to: &Self::VertexId) {
454 <#field_type as #gryf::core::GraphFull<V, E>>::remove_edges_between(&mut self.#field_name, from, to)
455 }
456
457 fn remove_edge_any_between(&mut self, from: &Self::VertexId, to: &Self::VertexId) -> Option<E> {
458 <#field_type as #gryf::core::GraphFull<V, E>>::remove_edge_any_between(&mut self.#field_name, from, to)
459 }
460
461 fn clear_edges(&mut self) {
462 <#field_type as #gryf::core::GraphFull<V, E>>::clear_edges(&mut self.#field_name)
463 }
464 }
465 };
466
467 TokenStream::from(implemented)
468}
469
470#[proc_macro_derive(MultiEdge, attributes(graph, gryf_crate))]
471pub fn multi_edge(tokens: TokenStream) -> TokenStream {
472 let input = parse_macro_input!(tokens as DeriveInput);
473
474 let gryf = util::get_gryf_path(&input);
475
476 let name = &input.ident;
477 let field = util::get_graph_field(&input);
478
479 let field_type = &field.ty;
480
481 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
482 let where_clause = util::augment_where_clause(
483 where_clause,
484 vec![(field_type.clone(), quote! { #gryf::core::props::MultiEdge })],
485 );
486
487 let implemented = quote! {
488 impl #impl_generics #gryf::core::props::MultiEdge for #name #ty_generics #where_clause {}
489 };
490
491 TokenStream::from(implemented)
492}
493
494#[proc_macro_derive(Guarantee, attributes(graph, gryf_crate))]
495pub fn guarantee(tokens: TokenStream) -> TokenStream {
496 let input = parse_macro_input!(tokens as DeriveInput);
497
498 let gryf = util::get_gryf_path(&input);
499
500 let name = &input.ident;
501 let field = util::get_graph_field(&input);
502
503 let field_type = &field.ty;
504
505 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
506 let where_clause = util::augment_where_clause(
507 where_clause,
508 vec![(field_type.clone(), quote! { #gryf::core::props::Guarantee })],
509 );
510
511 let implemented = quote! {
512 impl #impl_generics #gryf::core::props::Guarantee for #name #ty_generics #where_clause {
513 fn is_loop_free() -> bool {
514 <#field_type as #gryf::core::props::Guarantee>::is_loop_free()
515 }
516
517 fn has_paths_only() -> bool {
518 <#field_type as #gryf::core::props::Guarantee>::has_paths_only()
519 }
520
521 fn has_trees_only() -> bool {
522 <#field_type as #gryf::core::props::Guarantee>::has_trees_only()
523 }
524
525 fn has_bipartite_only() -> bool {
526 <#field_type as #gryf::core::props::Guarantee>::has_bipartite_only()
527 }
528
529 fn is_connected() -> bool {
530 <#field_type as #gryf::core::props::Guarantee>::is_connected()
531 }
532 }
533 };
534
535 TokenStream::from(implemented)
536}