1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::address::GalacticAddress;
5use crate::biome::{Biome, BiomeSubType};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13pub struct SystemId(pub u64);
14
15impl SystemId {
16 pub fn from_address(addr: &GalacticAddress) -> Self {
18 let packed = addr.packed() & 0x0FFF_FFFF_FFFF;
20 SystemId(packed)
21 }
22}
23
24#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
28#[non_exhaustive]
29pub struct System {
30 pub address: GalacticAddress,
31 pub name: Option<String>,
32 pub discoverer: Option<String>,
33 pub timestamp: Option<DateTime<Utc>>,
34 pub planets: Vec<Planet>,
35}
36
37impl System {
38 pub fn new(
39 address: GalacticAddress,
40 name: Option<String>,
41 discoverer: Option<String>,
42 timestamp: Option<DateTime<Utc>>,
43 planets: Vec<Planet>,
44 ) -> Self {
45 Self {
46 address,
47 name,
48 discoverer,
49 timestamp,
50 planets,
51 }
52 }
53
54 pub fn reality_index(&self) -> u8 {
56 self.address.reality_index
57 }
58}
59
60#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
62#[cfg_attr(
63 feature = "archive",
64 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
65)]
66#[non_exhaustive]
67pub struct Planet {
68 pub index: u8,
70 pub biome: Option<Biome>,
71 pub biome_subtype: Option<BiomeSubType>,
72 pub infested: bool,
74 pub name: Option<String>,
75 pub seed_hash: Option<u64>,
77}
78
79impl Planet {
80 pub fn new(
81 index: u8,
82 biome: Option<Biome>,
83 biome_subtype: Option<BiomeSubType>,
84 infested: bool,
85 name: Option<String>,
86 seed_hash: Option<u64>,
87 ) -> Self {
88 Self {
89 index,
90 biome,
91 biome_subtype,
92 infested,
93 name,
94 seed_hash,
95 }
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn system_reality_index_from_address() {
105 let addr = GalacticAddress::new(0, 0, 0, 0x123, 0, 42);
106 let sys = System::new(addr, None, None, None, vec![]);
107 assert_eq!(sys.reality_index(), 42);
108 }
109
110 #[test]
111 fn planet_constructor() {
112 let p = Planet::new(3, Some(Biome::Lush), None, false, Some("Eden".into()), None);
113 assert_eq!(p.index, 3);
114 assert_eq!(p.biome, Some(Biome::Lush));
115 assert!(!p.infested);
116 }
117}