#[macro_export]
macro_rules! custom_graph{
{
pub $($rest:tt)*
} => {
custom_graph!{
[@privacy[pub]]
$($rest)*
}
};
{
struct $($rest:tt)*
} => {
custom_graph!{
[ @privacy[] ]
struct $($rest)*
}
};
{
[ @privacy $($stack:tt)* ]
struct $struct_name:ident
$($rest:tt)*
} => {
custom_graph!{
[@struct_name[$struct_name] @privacy $($stack)*] $($rest)*
}
};
{ [ @struct_name $($stack:tt)* ]
as $base_graph_name:ident $($rest:tt)*
} => {
custom_graph!{
[ @base_graph_name[$base_graph_name] @generics[] @struct_name $($stack)* ] $($rest)*
}
};
{ [ @generics $($stack:tt)* ]
as $base_graph_name:ident $($rest:tt)*
} => {
custom_graph!{
[ @base_graph_name[$base_graph_name] @generics $($stack)* ] $($rest)*
}
};
{
[ @generics $($stack:tt)* ]
use $($rest:tt)*
} => {
custom_graph!{
[@constraint_wrappers[] @generics $($stack)* ] $($rest)*
}
};
{ [ @constraint_wrappers[$($wraps:tt)*] $($stack:tt)* ]
$(,)*impl $($rest:tt)*
} => {
custom_graph!{
[@constraints[] @constraint_wrappers[$($wraps)*] $($stack)* ] $($rest)*
}
};
{ [ @generics $base_graph_generics:tt @base_graph_name $($stack:tt)* ]
impl $($rest:tt)*
} => {
custom_graph!{
[@constraints[] @constraint_wrappers[] @generics $base_graph_generics @base_graph_name $($stack)* ] $($rest)*
}
};
{ [ @generics $base_g:tt @base_graph_name $($stack:tt)*] where $($rest:tt)*
}=>{
custom_graph!{
[ @constraint_wrappers[]
@generics $base_g
@base_graph_name
$($stack)*
]
where
$($rest)*
}
};
{ [ @constraint_wrappers $($stack:tt)*] $(,)*where $($rest:tt)*
}=>{
custom_graph!{
[ @constraints[]
@constraint_wrappers
$($stack)*
]
where
$($rest)*
}
};
{ [ @constraints $($stack:tt)*] $(,)* where $($rest:tt)*
}=>{
custom_graph!{
[ @where_clause[[]]
@constraints
$($stack)*
]
$($rest)*
}
};
{ [ @where_clause[[$($current_group:tt)*] $($rest_groups:tt)*] $($stack:tt)*]
$next:tt , $($rest:tt)+
}=>{
custom_graph!{
[ @where_clause[[][$($current_group)* $next] $($rest_groups)*]
$($stack)*
]
$($rest)+
}
};
{ [ @where_clause[[$($current_group:tt)*] $($rest_groups:tt)*] $($stack:tt)*]
$next:tt ,
}=>{
custom_graph!{
[ @where_clause[[$($current_group)* $next] $($rest_groups)*]
$($stack)*
]
}
};
{ [ @where_clause[[$($current_group:tt)*] $($rest_groups:tt)*] $($stack:tt)*]
$next:tt $($rest:tt)*
}=>{
custom_graph!{
[ @where_clause[[$($current_group)* $next] $($rest_groups)*]
$($stack)*
]
$($rest)*
}
};
{ [ @struct_name $($stack:tt)*]
< $($rest:tt)*
}=>{
custom_graph!{
[@generics[<] @struct_name $($stack)* ] $($rest)*
}
};
{ [ @base_graph_name $($stack:tt)*]
< $($rest:tt)*
}=>{
custom_graph!{
[@generics[<] @base_graph_name $($stack)* ] $($rest)*
}
};
{ [@generics[$($generics:tt)*] $($stack:tt)*]
> $($rest:tt)*
}=>{
custom_graph!{
[@generics[$($generics)* >] $($stack)* ] $($rest)*
}
};
{ [@generics[$($generics:tt)*] $($stack:tt)*]
$next:tt $($rest:tt)*
}=>{
custom_graph!{
[@generics[$($generics)* $next] $($stack)* ] $($rest)*
}
};
{
[ @constraint_wrappers[$w:ident $($prev:tt)*] $($stack:tt)* ]
, $v:ident $($rest:tt)*
} => {
custom_graph!{
[@constraint_wrappers[$v $w $($prev)*] $($stack)* ] $($rest)*
}
};
{
[@constraint_wrappers[$($prev:tt)*] $($stack:tt)* ]
$v:ident $($rest:tt)*
} => {
custom_graph!{
[@constraint_wrappers[$v $($prev)*] $($stack)* ] $($rest)*
}
};
{
[ @constraints[] $($stack:tt)* ]
$v:ident $($rest:tt)*
} => {
custom_graph!{
[@constraints[[$v]] $($stack)* ] $($rest)*
}
};
{
[@constraints[ $($other_constraints:tt)+ ] $($stack:tt)* ]
, $next:ident $($rest:tt)*
} => {
custom_graph!{
[@constraints[[$next]$($other_constraints)+] $($stack)* ] $($rest)*
}
};
{
@add_until
[[$($into:tt)*] $($stack:tt)*]
[$next:tt > $($rest:tt)*]
>
}=>{
};
{ [ @generics $($stack:tt)*]
} => {
custom_graph!{ [@constraint_wrappers[] @generics $($stack)*]}
};
{ [ @constraint_wrappers $($stack:tt)*] $(,)*
} => {
custom_graph!{ [@constraints[] @constraint_wrappers $($stack)*]}
};
{ [ @constraints $($stack:tt)*] $(,)*
} => {
custom_graph!{ [@where_clause[] @constraints $($stack)*]}
};
{ [ @where_clause $($stack:tt)*]
} => {
custom_graph!{@declare_struct_and_impl_minimum [@where_clause $($stack)*]}
custom_graph!{@impl_constraint_traits [@where_clause $($stack)*]}
};
{
@declare_struct_and_impl_minimum
[$($stack:tt)*]
}=>{
custom_graph!{@declare_struct [$($stack)*]}
custom_graph!{@impl_graph_wrapper [$($stack)*]}
custom_graph!{@impl_base_graph [$($stack)*]}
custom_graph!{@impl_contained_graph [$($stack)*]}
custom_graph!{@derive_debug [$($stack)*]}
custom_graph!{@derive_clone [$($stack)*]}
};
{
@declare_struct
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy[]
]
}=>{
struct $struct_name $($struct_generics)*
where $($($where_clause)* ,)*
{
wraps:
custom_graph!{
@in_struct
$($constraint_wrappers,$base_graph_name>>)*
$base_graph_name $($base_generics)*
}
}
};
{
@declare_struct
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy[pub]
]
}=>{
pub struct $struct_name $($struct_generics)*
where $($($where_clause)* ,)*
{
wraps:
custom_graph!{
@in_struct
$($constraint_wrappers,$base_graph_name>>)*
$base_graph_name $($base_generics)*
}
}
};
{
@impl_graph_wrapper
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*]@struct_name[$struct_name:ident]
@privacy$privacy:tt
]
}=>{
impl$($struct_generics)* $crate::core::GraphWrapper for $struct_name $($struct_generics)*
where $($($where_clause)* ,)*
{
custom_graph!{
@as_associated
custom_graph!{
@in_struct
$($constraint_wrappers,$base_graph_name >>)*
$base_graph_name $($base_generics)*
}
}
fn wrap(g: Self::Wrapped) -> Self{
$struct_name{wraps: g}
}
fn wrapped(&self) -> &Self::Wrapped{
&self.wraps
}
fn wrapped_mut(&mut self) -> &mut Self::Wrapped{
&mut self.wraps
}
fn unwrap(self) -> Self::Wrapped{
self.wraps
}
}
};
{
@impl_base_graph
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[<$T1:ty,$T2:ty>] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy$privacy:tt
]
}=>{
impl$($struct_generics)* $crate::core::BaseGraph for $struct_name$($struct_generics)*
where $($($where_clause)* ,)*
{
type Vertex = $T1;
type Weight = $T2;
type VertexIter = <<Self as $crate::core::GraphWrapper>::Wrapped as $crate::core::BaseGraph>::VertexIter;
type EdgeIter = <<Self as $crate::core::GraphWrapper>::Wrapped as $crate::core::BaseGraph>::EdgeIter;
fn empty_graph() -> Self{
$struct_name::wrap(
<Self as $crate::core::GraphWrapper>::Wrapped::empty_graph()
)
}
wrapped_method!{all_vertices(&self) -> Self::VertexIter}
wrapped_method!{all_edges(&self) -> Self::EdgeIter}
wrapped_method!{add_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
wrapped_method!{remove_vertex(&mut self, v: Self::Vertex) -> Result<(), ()>}
wrapped_method!{add_edge(&mut self, e: $crate::core::BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
wrapped_method!{remove_edge(&mut self, e: $crate::core::BaseEdge<Self::Vertex, Self::Weight>) -> Result<(), ()>}
}
};
{
@impl_contained_graph
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy$privacy:tt
]
}=>{
impl$($struct_generics)* $crate::core::ConstrainedGraph for $struct_name$($struct_generics)*
where $($($where_clause)* ,)*
{
wrapped_method!{invariant_holds(&self) -> bool}
wrapped_uncon_methods!{}
}
};
{
@derive_debug
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy$privacy:tt
]
}=>{
impl$($struct_generics)* std::fmt::Debug for $struct_name$($struct_generics)*
where $($($where_clause)* + std::fmt::Debug,)*
{
fn fmt(&self, f:&mut std::fmt::Formatter) -> std::fmt::Result{
write!(f, "{} {{ wraps: {:?} }}", stringify!($struct_name$($struct_generics)*), self.wraps)
}
}
};
{
@derive_clone
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[$($constraints:tt)*] @constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy$privacy:tt
]
}=>{
impl$($struct_generics)* Clone for $struct_name$($struct_generics)*
where $($($where_clause)* ,)*
{
fn clone(&self) -> $struct_name$($struct_generics)*{
$struct_name::wrap(self.wraps.clone())
}
}
};
{
@impl_constraint_traits
[ @where_clause[$([$($where_clause:tt)*])*]
@constraints[[$first_con_trait:ident] $($constraints:tt)*]
@constraint_wrappers[$($constraint_wrappers:tt)*]
@generics[$($base_generics:tt)*] @base_graph_name[$base_graph_name:ident]
@generics[$($struct_generics:tt)*] @struct_name[$struct_name:ident]
@privacy$privacy:tt
]
}=>{
impl$($struct_generics)* $first_con_trait for $struct_name$($struct_generics)*
where $($($where_clause)* ,)*
{}
custom_graph!{@impl_constraint_traits
[ @where_clause[$([$($where_clause)*])*]
@constraints[$($constraints)*]
@constraint_wrappers[$($constraint_wrappers)*]
@generics[$($struct_generics)*] @base_graph_name[$base_graph_name]
@generics[$($struct_generics)*] @struct_name[$struct_name]
@privacy $privacy
]
}
};
{
@impl_constraint_traits
[ @where_clause $where_clause:tt
@constraints[] $($rest_stack:tt)*]
}=>{};
{
@as_associated
$($rest:tt)*
}=>{
type Wrapped = $($rest)* ;
};
{
@in_struct
$con_graph:ident,$base_graph_name:ident >>
$($rest:tt)*
} => {
$con_graph<
custom_graph!{
@in_struct
$($rest)*
}
>
};
{
@in_struct
$base_graph_name:ident $($base_generics:tt)*
}=>{
$base_graph_name$($base_generics)*
};
}