ed_journals/modules/exobiology/models/
variant_source.rs

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
use std::str::FromStr;

use serde::{Deserialize, Serialize};
use serde_json::Value;
use thiserror::Error;

use crate::modules::galaxy::StarClass;
use crate::modules::materials::Material;

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum VariantSource {
    StarClass(StarClass),
    Material(Material),
}

#[derive(Debug, Error)]
pub enum VariantSourceError {
    #[error("Failed to parse variant source: {0}")]
    FailedToParse(#[source] serde_json::Error),

    #[error(
        "The provided material cannot be used as a variant source as it's not a raw material."
    )]
    NotARawMaterial,
}

impl FromStr for VariantSource {
    type Err = VariantSourceError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let variant_source = serde_json::from_value(Value::String(s.to_ascii_lowercase()))
            .map_err(VariantSourceError::FailedToParse)?;

        if let VariantSource::Material(material) = &variant_source {
            if !material.is_raw() {
                return Err(VariantSourceError::NotARawMaterial);
            }
        }

        Ok(variant_source)
    }
}