feagi_data_serialization/
feagi_serializable.rs

1use std::any::Any;
2use std::fmt::Debug;
3use feagi_data_structures::{FeagiDataError, FeagiJSON};
4use feagi_data_structures::neuron_voxels::xyzp::CorticalMappedXYZPNeuronVoxels;
5use crate::{FeagiByteContainer, FeagiByteStructureType};
6
7/// Trait for structures that can be serialized to and from FEAGI byte format.
8/// 
9/// Implementations must provide methods for determining their type, version,
10/// size requirements, and serialization/deserialization logic. The trait includes
11/// default validation methods for type and version checking.
12pub trait FeagiSerializable: Debug + Any {
13
14    /// Returns the structure type identifier.
15    fn get_type(&self) -> FeagiByteStructureType;
16
17    /// Returns the version number of this structure format.
18    fn get_version(&self) -> u8;
19
20    /// Returns the total number of bytes needed for serialization.
21    fn get_number_of_bytes_needed(&self) -> usize;
22
23    /// Serializes this structure into the provided byte slice.
24    /// 
25    /// The slice must be exactly the size returned by `get_number_of_bytes_needed`.
26    fn try_serialize_struct_to_byte_slice(&self, byte_destination: &mut [u8]) -> Result<(), FeagiDataError>;
27
28    /// Deserializes data from a byte slice and updates this structure.
29    fn try_deserialize_and_update_self_from_byte_slice(&mut self, byte_reading: &[u8]) -> Result<(), FeagiDataError>;
30
31    /// Provide access to `Any` trait for downcasting
32    fn as_any(&self) -> &dyn Any;
33
34    /// Verifies that a byte slice contains data of the correct type.
35    fn verify_byte_slice_is_of_correct_type(&self, byte_source: &[u8]) -> Result<(), FeagiDataError> {
36
37        if byte_source.len() <= FeagiByteContainer::STRUCT_HEADER_BYTE_COUNT {
38            return Err(FeagiDataError::DeserializationError(
39                format!("Byte slice needs to be at least {} bytes long to be considered valid! Given slice is {} elements long!", FeagiByteContainer::STRUCT_HEADER_BYTE_COUNT, byte_source.len())
40            ))
41        }
42        if byte_source[0] != self.get_type() as u8 {
43            return Err(FeagiDataError::DeserializationError(format!("Attempted to process byte slice as structure type {} when given slice seems to be type {}!", self.get_type(), byte_source[0])))
44        }
45        Ok(())
46    }
47
48    /// Verifies that a byte slice contains data of the correct version.
49    fn verify_byte_slice_is_of_correct_version(&self, byte_source: &[u8]) -> Result<(), FeagiDataError> {
50
51        if byte_source.len() < FeagiByteContainer::STRUCT_HEADER_BYTE_COUNT {
52            return Err(FeagiDataError::DeserializationError(
53                format!("Byte slice needs to be at least {} bytes long to be considered valid! Given slice is {} elements long!", FeagiByteContainer::STRUCT_HEADER_BYTE_COUNT, byte_source.len())
54            ))
55        }
56        if byte_source[1] != self.get_version() {
57            return Err(FeagiDataError::DeserializationError(format!("Current implementation of Feagi Data Serialization supports structure ID {} of version {}, however version {} was given!!", self.get_type(), self.get_version(), byte_source[1])))
58        }
59        Ok(())
60    }
61
62    // TODO universal method to export as a new FBS
63}
64
65// TODO there is cloning here, can it be avoided?
66
67impl TryFrom<Box<dyn FeagiSerializable>> for FeagiJSON {
68    type Error = FeagiDataError;
69    fn try_from(value: Box<dyn FeagiSerializable>) -> Result<Self, Self::Error> {
70        let option = value.as_any().downcast_ref::<FeagiJSON>();
71        match option {
72            Some(value) => Ok(value.clone()),
73            None => Err(FeagiDataError::DeserializationError("This struct is not a FeagiJSON struct and cannot be deserialized as such!".into()))
74        }
75    }
76}
77
78impl TryFrom<Box<dyn FeagiSerializable>> for CorticalMappedXYZPNeuronVoxels {
79    type Error = FeagiDataError;
80    fn try_from(value: Box<dyn FeagiSerializable>) -> Result<Self, Self::Error> {
81        let option = value.as_any().downcast_ref::<CorticalMappedXYZPNeuronVoxels>();
82        match option {
83            Some(value) => Ok(value.clone()),
84            None => Err(FeagiDataError::DeserializationError("This struct is not a CorticalMappedXYZPNeuronVoxels struct and cannot be deserialized as such!".into()))
85        }
86    }
87}