1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! # Flexpiler
//!
//! A library that aims to maximize customisation of serialization.
//!
//! Most notably this library provides the derive macro ```flexpiler::Deserialize``` as well as some common
//! implementations in the ```flexpiler::common``` namespace.
//!
//! Currently the project only supports deserialization of a format that mirrors how structs and enums
//! are initialized in the rust language.
//!
//! # examples
//!
//! ```
//! #[derive(flexpiler::Deserialize)]
//! struct Example {
//!   field_i32: i32,
//! }
//!
//! let mut string_reader = flexpiler::common::reader::String::from("Example{ field_i32: 5 }");
//!
//! let example = match Example::deserialize(&mut string_reader) {
//!     Ok(example) => example,
//!     Err(error) => {
//!         assert!(false, "deserialisation failed: {}", error);
//!     }
//! };
//!
//! assert_eq!(example.field_i32, 5);
//! ```
//!


pub mod block;
pub mod common;
pub mod deserializer;
pub use error::Error;
pub mod error;
pub mod format;
pub mod parser;
pub mod reader;


pub trait Deserialization<FormatType: crate::format::Trait>: Sized {
    type Deserializer: crate::deserializer::Trait<Self, FormatType::DeserializerContext>;
}


pub trait Deserialize<FormatType>: Sized {
    fn deserialize<ReaderType>(reader_mut_ref: &mut ReaderType)
        -> Result<Self, error::Error>
    where ReaderType: reader::Trait;
}


impl<DataType, FormatType> Deserialize<FormatType> for DataType
where DataType: Deserialization<FormatType>,
      FormatType: crate::format::Trait,
{
    fn deserialize<ReaderType>(reader_mut_ref: &mut ReaderType) -> Result<Self, Error> where ReaderType: reader::Trait {
        use deserializer::Trait;

        return match DataType::Deserializer::deserialize(reader_mut_ref) {
            Ok(deserializer_result) => {
                Ok(deserializer_result.data)
            },
            Err(error) => Err(error),
        }
    }
}


#[macro_use]
extern crate flexpiler_derive;
pub use flexpiler_derive::*;


#[cfg(test)]
mod tests {
    macro_rules! matches(
        ($e:expr, $p:pat) => (
            match $e {
                $p => true,
                _ => false
            }
        )
    );

    #[test]
    fn common_reader_string_test() {
        use crate::common;
        use crate::reader;
        use crate::reader::Trait;

        let mut reader = common::reader::String::from("Blba");

        println!("'B' as u8: {}", 'B' as u8);
        println!("'l' as u8: {}", 'l' as u8);
        println!("'b' as u8: {}", 'b' as u8);
        println!("'a' as u8: {}", 'a' as u8);

        assert!(matches![reader.read(), reader::Result::Ok(66)]);
        assert!(matches![reader.read(), reader::Result::Ok(108)]);
        assert!(matches![reader.read(), reader::Result::Ok(98)]);
        assert!(matches![reader.read(), reader::Result::Ok(97)]);
        assert!(matches![reader.read(), reader::Result::EndOfFile]);
    }

    #[test]
    fn common_deserializer_string_test() {
        use crate::common;
        use crate::reader;
        use crate::reader::Trait;

        use crate::Deserialize;

        let mut reader = common::reader::String::from("\"toss a witch\"");
        let deserialized_result = std::string::String::deserialize(&mut reader);
        assert!(deserialized_result.is_ok());
        if let Ok(deserialized) = deserialized_result {
            println!("Deserialized string: {}", deserialized);
            assert_eq!(deserialized.as_str(), "toss a witch");
        }
    }
}