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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! Error type of Perestroika.

use std::fmt;

use crate::node_gene::DepthType;

#[derive(Debug)]
/// A collection of errors that Perestroika can generate.
pub enum PerestroikaError {
    /// Raised when a NodeGene is missing an index value.
    NodeGeneMissingIndex,
    /// Raised when a NodeGene is missing a depth value.
    NodeGeneMissingDepth,
    /// Raised when trying to create a ConnectionGene which already exists in a Genome.
    ConnectionGeneAlreadyExists,
    /// Raised when a ConnectionGene is missing a source NodeGene.
    ConnectionGeneMissingSource,
    /// Raised when a ConnectionGene is missing a target NodeGene.
    ConnectionGeneMissingTarget,
    /// Raised when a ConnectionGene is missing a weight value.
    ConnectionGeneMissingWeight,
    /// Raised when a ConnectionGene is missing an enabled/disabled status.
    ConnectionGeneMissingEnabledStatus,
    /// Raised when a ConnectionGene has the soure and target NodeGenes are on the same depth.
    ConnectionGeneSourceAndTargetSameDepth {
        /// The depth of the Layer.
        depth: DepthType,
    },
    /// Raised when a ConnectionGene has a source NodeGene deeper than the target NodeGene.
    ConnectionGeneSourceDeeperThanTarget {
        /// The depth of the source NodeGene.
        source: DepthType,
        /// The depth of the target NodeGene.
        target: DepthType,
    },
    /// Raised when a Genome is created without NodeGenes.
    ///
    /// A Genome must have at least two Layers, an Input and Output, on each at least a single
    /// NodeGene.
    GenomeMissingNodeGenes,
    /// Raised when a Genome is created without Input NodeGenes.
    GenomeWithoutInputNodeGenes,
    /// Raised when a Genome is created without Output NodeGenes.
    GenomeWithoutOutputNodeGenes,
    /// Raised if an operation on a Genome requires ConnectionGenes, but the Genome has none.
    GenomeMissingConnectionGenes,
    /// Raised when an operation on a Genome tries to create a new NodeGene, but the Genome has the
    /// maximum amount of NodeGenes.
    GenomeMaxNodeGenesReached,
    /// Raised when an operation on a Genome tries to create a new ConnectionGene, but the Genome
    /// has the maximum amount of ConnectionGenes.
    GenomeMaxConnectionsReached,
    /// Raised when an operation on the Genome tries to access a hidden layer, but there are none.
    GenomeIsTooShallow,
    /// Raised when an operation on a Genome requires a removal of a NodeGene from a Layer, but the
    /// Layer has a single NodeGene.
    LayerMustHaveMoreThanOneNodeGene,
    /// Raised when a Layer is created without a depth value.
    LayerMustHaveDepthType,
    /// Raised when a Genome tries to propagate the inputs but the input's length differs from the
    /// input Layer's length.
    LayerInputLengthMismatch,
    /// A currently undocumented error.
    UnhandledError {
        /// Text of the undocumented error.
        text: String,
    },
}
impl fmt::Display for PerestroikaError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::NodeGeneMissingIndex => write!(f, "NodeGene is missing an index."),
            Self::NodeGeneMissingDepth => write!(f, "NodeGene is missing depth."),
            Self::ConnectionGeneAlreadyExists => {
                write!(f, "ConnectionGene already exists in place.")
            }
            Self::ConnectionGeneMissingSource => write!(f, "ConnectionGene source is missing."),
            Self::ConnectionGeneMissingTarget => write!(f, "ConnectionGene target is missing."),
            Self::ConnectionGeneMissingWeight => write!(f, "ConnectionGene weight is missing."),
            Self::ConnectionGeneMissingEnabledStatus => {
                write!(f, "ConnectionGene enabled status is missing.")
            }
            Self::ConnectionGeneSourceAndTargetSameDepth { depth } => {
                write!(
                    f,
                    "ConnectionGene source and target are in the same depth: {depth:?}."
                )
            }
            Self::ConnectionGeneSourceDeeperThanTarget { source, target } => {
                write!(f, "ConnectionGene's source is deeper than the target: Source :{source:?} -> Target: {target:?}.")
            }
            Self::GenomeMissingNodeGenes => write!(f, "Genome is missing NodeGenes."),
            Self::GenomeWithoutInputNodeGenes => {
                write!(f, "Genome is missing NodeGenes of Input type.")
            }
            Self::GenomeWithoutOutputNodeGenes => {
                write!(f, "Genome is missing NodeGenes of Output type.")
            }
            Self::GenomeMissingConnectionGenes => write!(f, "Genome is missing ConnectionGenes."),
            Self::GenomeMaxNodeGenesReached => {
                write!(f, "Genome has the maximum amount of NodeGenes.")
            }
            Self::GenomeMaxConnectionsReached => {
                write!(f, "Genome has the maximum amount of ConnectionGenes.")
            }
            Self::GenomeIsTooShallow => {
                write!(
                    f,
                    "Genome must contain at least an Input and Output layers."
                )
            }
            Self::LayerMustHaveMoreThanOneNodeGene => {
                write!(f, "Layer must have more than one NodeGene.")
            }
            Self::LayerMustHaveDepthType => {
                write!(f, "Layer must have a DepthType specified.")
            }
            Self::LayerInputLengthMismatch => {
                write!(
                    f,
                    "Input Layer and input vector do not have the same length."
                )
            }
            Self::UnhandledError { text } => {
                write!(f, "Unhandled error:\n{text}")
            }
        }
    }
}