format-ende 0.1.1

Set of traits allowing to encode/decode data from/to a generic format
Documentation
use std::io::Cursor;

use format_ende::{FormatDecoder, FormatDecoderDyn, FormatEncoder, FormatEncoderDyn};

/// Dummy data struct
#[derive(Debug, PartialEq, Eq)]
struct Foo {
    foo: i32,
}

/// Dummy data format
struct BarFormat;

/// Implement encoding logic for `Foo` in `BarFormat`
impl FormatEncoder<Foo> for BarFormat {
    type EncodeError = std::io::Error;

    fn encode(
        &mut self,
        mut writer: impl std::io::Write,
        value: &Foo,
    ) -> Result<(), Self::EncodeError> {
        writeln!(writer, "Foo: {}", value.foo)
    }
}

/// Implement decoding logic for `Foo` in `BarFormat`
impl FormatDecoder<Foo> for BarFormat {
    type DecodeError = std::io::Error;

    fn decode(&mut self, mut reader: impl std::io::Read) -> Result<Foo, Self::DecodeError> {
        let mut str = String::new();
        reader.read_to_string(&mut str)?;
        let foo = str.trim().strip_prefix("Foo: ").unwrap().parse().unwrap();
        Ok(Foo { foo })
    }
}

fn main() {
    // Buffer to encode into and decode from
    let mut buf: Vec<u8> = Vec::new();

    // Create the format instance, ...
    let mut format = BarFormat;

    {
        // ... create the trait object for encoding...
        let format = &mut format as &mut dyn FormatEncoderDyn<Foo>;

        // ... and use it to encode a value
        format.encode_dyn(&mut buf, &Foo { foo: 42 }).unwrap();
    }

    {
        // ... create the trait object for decoding...
        let format = &mut format as &mut dyn FormatDecoderDyn<Foo>;

        // ... and use it to decode the value
        let value = format.decode_dyn(&mut Cursor::new(buf)).unwrap();
        assert_eq!(value, Foo { foo: 42 });
    }
}