enneagram 1.3.0

A digital enneagram
use core::ops::Deref;
use std::{borrow::Cow, boxed::Box, format, string::String, vec::Vec};

use serde::{Deserialize, Deserializer, Serialize, Serializer};

crate::config::def_unitary!(
    struct EdgeConfig for PartialEdgeConfig
    {
        name: str,
        pivot: str,
        digit: Digit
    }
);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Digit(Box<[[i8; 2]]>);

impl Deref for Digit
{
    type Target = [[i8; 2]];

    fn deref(&self) -> &Self::Target
    {
        &self.0
    }
}

impl Serialize for Digit
{
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer
    {
        let Self(curve) = self;

        curve.iter().map(|[x, y]| format!("{x},{y}")).collect::<Vec<_>>().join(" ").serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for Digit
{
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>
    {
        let curve = String::deserialize(deserializer)?
            .split(" ")
            .map(|xy| {
                xy.split(",")
                    .map(|e| e.parse::<i8>().expect("Failed parsing 8-bit int coordinate of digit."))
                    .collect::<Vec<_>>()
                    .try_into()
                    .expect("Each point of the digit must contain exactly two coordinates.")
            })
            .collect::<Vec<_>>()
            .into();

        Ok(Self(curve))
    }
}