dager 0.1.1

Crate to create and execute a graph of nodes.
Documentation
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */


use std::any::TypeId;

use crate::DErr;
use crate::collections::OutCol;
use crate::edge::Edge;


///An out signature must be able to save which idx of an node's output ports are connected.
pub trait OutSignature{
    fn set_edge(&mut self, edge: Edge) -> Result<(), DErr>;
    fn remove_edge(&mut self, port_idx: usize) -> Result<Edge, DErr>;
}

/*
impl<A, B> OutSignature for (OutCol<A>, OutCol<B>) where A: Send + 'static, B: Send + 'static{
    fn set_edge(&mut self, edge: Edge) -> Result<(), DErr> {
	match edge.start_idx{
	    0 => {
		if TypeId::of::<A>() == edge.type_id{
		    return Err(DErr::TypeMissmatch);
		}
		self.0.edge = Some(edge)
	    },
	    1 => {
		if TypeId::of::<B>() == edge.type_id{
		    return Err(DErr::TypeMissmatch);
		}
		self.1.edge = Some(edge)
	    },
	    _ => return Err(DErr::NoSuchPort),
	}

	Ok(())
    }
}
*/

impl<A> OutSignature for OutCol<A> where A: Send + 'static{
    fn set_edge(&mut self, edge: Edge) -> Result<(), DErr> {
	if edge.start_idx == 0{
	    if TypeId::of::<A>() != edge.type_id{
		return Err(DErr::TypeMissmatch);
	    }
	    self.edge = Some(edge);
	}else{
	    return Err(DErr::NoSuchPort);
	}
	Ok(())
    }

    
    fn remove_edge(&mut self, port_idx: usize) -> Result<Edge, DErr>{
	if port_idx == 0{
	    if let Some(old_edge) = self.edge.take(){
		Ok(old_edge)
	    }else{
		Err(DErr::NoEdgeOnIdx)
	    }
	}else{
	    Err(DErr::NoSuchPort)
	}
    }
}

impl OutSignature for (){
    fn set_edge(&mut self, _edge: Edge) -> Result<(), DErr> {
	Err(DErr::NoSuchPort)
    }
    
    fn remove_edge(&mut self, _port_idx: usize) -> Result<Edge, DErr>{
	Err(DErr::NoSuchPort)
    }
}


///Implemets the OutSignature trait for any tupel of the for (A, B, C, ...) denoted as impl_outsig!(A:0, B:1, C:2, ...);
#[macro_export]
macro_rules! impl_outsig {
    ($($Gen:ident : $Idx:tt), +) => {
	impl<$($Gen),+> OutSignature for ($(OutCol<$Gen>),+) where $($Gen : Send + 'static),+{
	    fn set_edge(&mut self, edge: Edge) -> Result<(), DErr>{
		match edge.start_idx{
		    $($Idx => {
			if TypeId::of::<$Gen>() != edge.type_id{
			    return Err(DErr::TypeMissmatch);
			}
			self.$Idx.edge = Some(edge)
		    }),+
		    _ => return Err(DErr::NoSuchPort),
		}

		Ok(())
	    }
	    
	    fn remove_edge(&mut self, port_idx: usize) -> Result<Edge, DErr>{
		match port_idx{
		    $($Idx => {
			if let Some(old_edge) = self.$Idx.edge.take(){
			    Ok(old_edge)
			}else{
			    Err(DErr::NoEdgeOnIdx)
			}
		    }), +
			_ => Err(DErr::NoSuchPort)
		}
		
	    }
	}
    };
}


impl_outsig!(A:0, B:1);
impl_outsig!(A:0, B:1, C:2);
impl_outsig!(A:0, B:1, C:2, D:3);
impl_outsig!(A:0, B:1, C:2, D:3, E:4);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20, V:21);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20, V:21, W:22);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20, V:21, W:22, X:23);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20, V:21, W:22, X:23, Y:24);
impl_outsig!(A:0, B:1, C:2, D:3, E:4, F:5, G:6, H:7, I:8, J:9, K:10, L:11, M:12, N:13, O:14, P:15, Q:16, R:17, S:18, T:19, U:20, V:21, W:22, X:23, Y:24, Z:25);