khora_data/scene/strategy.rs
1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Defines the abstract contract for serialization strategies and their associated types.
16
17use crate::ecs::World;
18use std::fmt;
19
20/// An error that can occur during the serialization process.
21#[derive(Debug)]
22pub enum SerializationError {
23 /// Indicates a failure during I/O or data conversion.
24 ProcessingFailed(String),
25}
26
27/// An error that can occur during the deserialization process.
28#[derive(Debug)]
29pub enum DeserializationError {
30 /// The data is corrupted or does not match the expected format.
31 InvalidFormat(String),
32 /// A failure occurred while populating the world.
33 WorldPopulationFailed(String),
34}
35
36impl fmt::Display for SerializationError {
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 match self {
39 SerializationError::ProcessingFailed(msg) => {
40 write!(f, "Serialization failed: {}", msg)
41 }
42 }
43 }
44}
45
46impl fmt::Display for DeserializationError {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 match self {
49 DeserializationError::InvalidFormat(msg) => {
50 write!(f, "Deserialization failed: Invalid format - {}", msg)
51 }
52 DeserializationError::WorldPopulationFailed(msg) => {
53 write!(f, "Deserialization failed: World population - {}", msg)
54 }
55 }
56 }
57}
58
59/// The abstract contract for a scene serialization strategy.
60///
61/// Each concrete implementation of this trait represents a different method
62/// of converting a `World` to and from a persistent format.
63pub trait SerializationStrategy {
64 /// Returns the unique, versioned string identifier for this strategy.
65 ///
66 /// This ID is written to the `SceneHeader` and used by the `SerializationService`
67 /// to look up the correct strategy from its registry during deserialization.
68 /// Example: `"KH_RECIPE_V1"`.
69 fn get_strategy_id(&self) -> &'static str;
70
71 /// Serializes the given `World` into a byte payload.
72 ///
73 /// # Arguments
74 /// * `world` - A reference to the world to be serialized.
75 ///
76 /// # Returns
77 /// A `Result` containing the binary payload `Vec<u8>` or a `SerializationError`.
78 fn serialize(&self, world: &World) -> Result<Vec<u8>, SerializationError>;
79
80 /// Deserializes data from a byte payload to populate the given `World`.
81 ///
82 /// This method should assume the `SceneHeader` has already been parsed and validated,
83 /// and that `data` is the correct payload for this strategy.
84 ///
85 /// # Arguments
86 /// * `data` - The raw byte payload to deserialize.
87 /// * `world` - A mutable reference to the world to be populated.
88 ///
89 /// # Returns
90 /// A `Result` indicating success or a `DeserializationError`.
91 fn deserialize(&self, data: &[u8], world: &mut World) -> Result<(), DeserializationError>;
92}