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
use serde::{Serialize, Serializer};

use necsim_partitioning_core::partition::PartitionSize;

#[cfg(any(
    feature = "gillespie-algorithms",
    feature = "independent-algorithm",
    feature = "cuda-algorithm"
))]
use rustcoalescence_algorithms::AlgorithmParamters;

#[derive(Debug, DeserializeState)]
#[serde(deserialize_state = "PartitionSize")]
pub enum Algorithm {
    #[cfg(feature = "gillespie-algorithms")]
    #[serde(alias = "Classical")]
    Gillespie(
        #[serde(deserialize_state)]
        <rustcoalescence_algorithms_gillespie::gillespie::GillespieAlgorithm as rustcoalescence_algorithms::AlgorithmParamters>::Arguments,
    ),
    #[cfg(feature = "gillespie-algorithms")]
    #[serde(alias = "SkippingGillespie")]
    EventSkipping(
        #[serde(deserialize_state)]
        <rustcoalescence_algorithms_gillespie::event_skipping::EventSkippingAlgorithm as AlgorithmParamters>::Arguments,
    ),
    #[cfg(feature = "cuda-algorithm")]
    #[serde(alias = "CUDA")]
    Cuda(#[serde(deserialize_state)] <rustcoalescence_algorithms_cuda::CudaAlgorithm as AlgorithmParamters>::Arguments),
    #[cfg(feature = "independent-algorithm")]
    Independent(
        #[serde(deserialize_state)] <rustcoalescence_algorithms_independent::IndependentAlgorithm as AlgorithmParamters>::Arguments,
    ),
}

impl Serialize for Algorithm {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        #[allow(unreachable_patterns, clippy::single_match_else)]
        match self {
            #[cfg(feature = "gillespie-algorithms")]
            Self::Gillespie(args) => {
                serializer.serialize_newtype_variant(stringify!(Algorithm), 0, "Gillespie", args)
            },
            #[cfg(feature = "gillespie-algorithms")]
            Self::EventSkipping(args) => serializer.serialize_newtype_variant(
                stringify!(Algorithm),
                1,
                "EventSkipping",
                args,
            ),
            #[cfg(feature = "cuda-algorithm")]
            Self::Cuda(args) => {
                serializer.serialize_newtype_variant(stringify!(Algorithm), 2, "CUDA", args)
            },
            #[cfg(feature = "independent-algorithm")]
            Self::Independent(args) => {
                serializer.serialize_newtype_variant(stringify!(Algorithm), 3, "Independent", args)
            },
            _ => {
                std::mem::drop(serializer);

                Err(serde::ser::Error::custom(
                    "rustcoalescence must be compiled to support at least one algorithm",
                ))
            },
        }
    }
}