Skip to main content

ed_journals/modules/exobiology/models/
variant_source.rs

1use std::str::FromStr;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5use thiserror::Error;
6
7use crate::modules::galaxy::StarClass;
8use crate::modules::materials::Material;
9
10#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
11#[serde(untagged)]
12pub enum VariantSource {
13    StarClass(StarClass),
14    Material(Material),
15}
16
17#[derive(Debug, Error)]
18pub enum VariantSourceError {
19    #[error("Failed to parse variant source: {0}")]
20    FailedToParse(#[source] serde_json::Error),
21
22    #[error(
23        "The provided material cannot be used as a variant source as it's not a raw material."
24    )]
25    NotARawMaterial,
26}
27
28impl FromStr for VariantSource {
29    type Err = VariantSourceError;
30
31    fn from_str(s: &str) -> Result<Self, Self::Err> {
32        let variant_source = serde_json::from_value(Value::String(s.to_ascii_lowercase()))
33            .map_err(VariantSourceError::FailedToParse)?;
34
35        if let VariantSource::Material(material) = &variant_source {
36            if !material.is_raw() {
37                return Err(VariantSourceError::NotARawMaterial);
38            }
39        }
40
41        Ok(variant_source)
42    }
43}