omg_serde 0.1.0

Adds serde support to omg_core.
Documentation
use crate::data::math::generator::generator1d::Generator1dSerde;
use crate::data::math::generator::noise::NoiseSerde;
use crate::data::math::size2d::Size2dSerde;
use anyhow::{Context, Result};
use omg_core::data::math::generator::generator1d::Generator1d;
use omg_core::data::math::generator::generator2d::Generator2d;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub enum Generator2dSerde {
    ApplyToX(Generator1dSerde),
    ApplyToY(Generator1dSerde),
    ApplyToDistance {
        generator: Generator1dSerde,
        center_x: u32,
        center_y: u32,
    },
    IndexGenerator(Size2dSerde),
    Noise2d(NoiseSerde),
}

type S = Generator2dSerde;
type R = Generator2d;

impl Generator2dSerde {
    pub fn try_convert(self) -> Result<Generator2d> {
        match self {
            S::ApplyToX(data) => {
                let generator = data
                    .try_convert()
                    .context("Failed to convert to Generator2d::ApplyToX!")?;
                Ok(R::ApplyToX(generator))
            }
            S::ApplyToY(data) => {
                let generator = data
                    .try_convert()
                    .context("Failed to convert to Generator2d::ApplyToY!")?;
                Ok(R::ApplyToY(generator))
            }
            S::ApplyToDistance {
                generator,
                center_x,
                center_y,
            } => {
                let generator: Generator1d = generator
                    .try_convert()
                    .context("Failed to convert to Generator2d::ApplyToDistance!")?;
                Ok(Generator2d::new_apply_to_distance(
                    generator, center_x, center_y,
                ))
            }
            S::IndexGenerator(size) => {
                let size = size
                    .try_convert()
                    .context("Failed to convert to Generator2d::IndexGenerator!")?;
                Ok(R::IndexGenerator(size))
            }
            S::Noise2d(noise) => {
                let noise = noise
                    .try_convert()
                    .context("Failed to convert to Generator2d::Noise1d!")?;
                Ok(R::Noise2d(noise))
            }
        }
    }
}

impl From<&Generator2d> for Generator2dSerde {
    fn from(generator: &Generator2d) -> Self {
        match generator {
            R::ApplyToX(generator) => S::ApplyToX(generator.into()),
            R::ApplyToY(generator) => S::ApplyToY(generator.into()),
            R::ApplyToDistance {
                generator,
                center_x,
                center_y,
            } => S::ApplyToDistance {
                generator: generator.into(),
                center_x: *center_x,
                center_y: *center_y,
            },
            R::IndexGenerator(size) => S::IndexGenerator(size.into()),
            R::Noise2d(noise) => S::Noise2d(noise.into()),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use omg_core::data::math::size2d::Size2d;

    #[test]
    fn test_convert_apply_to_x() {
        assert_eq(Generator2d::ApplyToX(Generator1d::InputAsOutput))
    }

    #[test]
    fn test_convert_apply_to_y() {
        assert_eq(Generator2d::ApplyToY(Generator1d::InputAsOutput))
    }

    #[test]
    fn test_convert_apply_to_distance() {
        assert_eq(Generator2d::ApplyToDistance {
            generator: Generator1d::InputAsOutput,
            center_x: 1,
            center_y: 2,
        })
    }

    #[test]
    fn test_convert_index_generator() {
        assert_eq(Generator2d::IndexGenerator(Size2d::unchecked(1, 2)))
    }

    fn assert_eq(start: Generator2d) {
        let serde: Generator2dSerde = (&start).into();

        assert_eq!(serde.try_convert().unwrap(), start)
    }
}