96 lines
1.7 KiB
Rust
Raw Normal View History

2023-12-24 23:03:00 -08:00
use anyhow::{bail, Result};
use cgmath::Point2;
use std::collections::HashMap;
use crate::physics::Pfloat;
/// Toml file syntax
pub(in crate::content) mod toml {
use super::Pfloat;
use serde::Deserialize;
use std::collections::HashMap;
#[derive(Debug, Deserialize)]
pub struct SystemRoot {
pub system: System,
pub object: HashMap<String, Object>,
}
#[derive(Debug, Deserialize)]
pub struct System {
pub name: String,
}
#[derive(Debug, Deserialize)]
pub struct Object {
pub sprite: String,
pub center: Center,
#[serde(default)]
pub radius: Pfloat,
#[serde(default)]
pub angle: Pfloat,
}
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum Center {
Label(String),
Coords([Pfloat; 2]),
}
}
#[derive(Debug)]
pub struct System {
name: String,
objects: Vec<Object>,
}
#[derive(Debug)]
struct Object {
sprite: String,
center: Point2<Pfloat>,
radius: Pfloat,
angle: Pfloat,
}
fn resolve_center(
objects: &HashMap<String, toml::Object>,
obj: &toml::Object,
) -> Option<Point2<f32>> {
match &obj.center {
toml::Center::Label(s) => resolve_center(&objects, objects.get(s)?),
toml::Center::Coords(v) => Some(Point2::from(*v)),
}
}
impl System {
pub fn parse(value: toml::SystemRoot) -> Result<Self> {
let mut objects = Vec::new();
for (_, obj) in &value.object {
let center = match resolve_center(&value.object, obj) {
Some(v) => v,
None => {
bail!(
"Failed to parse content file: could not resolve center label `{:?}`",
obj.center
);
}
};
objects.push(Object {
sprite: obj.sprite.clone(),
center,
radius: obj.radius,
angle: obj.angle,
});
}
return Ok(Self {
name: value.system.name.clone(),
objects,
});
}
}