bitsong 0.1.2

Fast `#[no_std]` macro-based serialization/deserialization.
Documentation
use bitsong_macros::{FromSong, SongSize, ToSong};
#[cfg(feature = "no_panic")]
use no_panic::no_panic;

use crate::*;

#[derive(Clone, Copy, Debug, PartialEq, Eq, FromSong, ToSong, SongSize)]
#[repr(u8)]
enum Color {
    Unknown = 0x00,
    Red = 0x01,
    Green = 0x02,
    Blue = 0x03
}

#[derive(Clone, Debug, PartialEq, Eq, FromSong, ToSong, SongSize)]
struct Cat {
    fluffy_paws: bool
}

#[derive(Clone, Debug, PartialEq, Eq, FromSong, ToSong, SongSize)]
#[song(discriminant(PetType = u8))]
enum Pet {
    Dog,
    Cat(Cat),
    Fish(Color)
}

#[derive(Clone, Debug, PartialEq, Eq, FromSong, ToSong, SongSize)]
struct Person {
    name: [u8; 16],
    age: u8,
    favorite_color: Color,
    pet: Option<Pet>
}

fn new_joe() -> Person {
    let mut name = [0; 16];
    name[0..3].copy_from_slice(b"Joe");
    Person {
        name,
        age: 21,
        favorite_color: Color::Green,
        pet: Some(Pet::Cat(Cat {
            fluffy_paws: true
        }))
    }
}

const JOE_SONG: [u8; 21] = [74, 111, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 2, 1, 1, 1];

#[test]
fn serialize() {
    let mut buf = [0; 21];
    new_joe().to_song(&mut buf).unwrap();
    assert_eq!(buf, JOE_SONG);
}

#[test]
fn deserialize() {
    let joe = Person::from_song(&JOE_SONG).unwrap();
    assert_eq!(joe, new_joe())
}

#[test]
fn round_trip() {
    let joe = new_joe();

    let mut buf = [0; 128];
    joe.to_song(&mut buf).unwrap();
    
    // we can revive him... we have the technology
    let joe_reconstructed = Person::from_song(&buf).unwrap();
    assert_eq!(joe, joe_reconstructed)
}

#[test]
fn const_song_size() {
    let whiskers = Cat {
        fluffy_paws: true
    };

    assert_eq!(whiskers.song_size(), Cat::SONG_SIZE)
}

#[test]
#[cfg(feature = "no_panic")]
#[no_panic]
fn serialize_cant_panic() {
    let joe = new_joe();

    let mut buf = [0; 128];
    joe.to_song(&mut buf).unwrap();
}

#[test]
#[cfg(feature = "no_panic")]
#[no_panic]
fn deserialize_cant_panic() {
    let joe = new_joe();

    let mut buf = [0; 128];
    joe.to_song(&mut buf).unwrap();
}