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
//! Types implementing the [Serializer] trait.
//!
//! There are currently three implementations:
//!
//! * SerdeSerializer uses the `serde` and `serde_json` crate to serialize
//! the test inputs (of arbitrary Serializable type) to a `.json` file.
//!
//! * [ByteSerializer] encodes and decodes values of type `Vec<u8>` by simply
//! copy/pasting the bytes from/to the files. The extension is customizable.
//!
//! * [StringSerializer] encodes and decodes values of any type implementing
//! `FromStr` and `ToString` into utf-8 encoded text files.

mod serde_serializer;
use std::{marker::PhantomData, str::FromStr};

pub use serde_serializer::SerdeSerializer;

use crate::Serializer;

/**
A Serializer for `Vec<u8>` that simply copies the bytes from/to the files.
*/
pub struct ByteSerializer {
    ext: &'static str,
}

impl ByteSerializer {
    /// Create a byte serializer. The only argument is the name of the extension
    /// that the created files should have. For example:
    /// ```
    /// use fuzzcheck::ByteSerializer;
    ///
    /// let ser = ByteSerializer::new("png");
    /// ````
    #[no_coverage]
    pub fn new(ext: &'static str) -> Self {
        Self { ext }
    }
}

impl crate::traits::Serializer for ByteSerializer {
    type Value = Vec<u8>;

    #[no_coverage]
    fn extension(&self) -> &str {
        self.ext
    }
    #[no_coverage]
    fn from_data(&self, data: &[u8]) -> Option<Self::Value> {
        Some(data.into())
    }
    #[no_coverage]
    fn to_data(&self, value: &Self::Value) -> Vec<u8> {
        value.clone()
    }
}

/**
A serializer that encodes and decodes values of any type implementing
`FromStr` and `ToString` into utf-8 encoded text files.
 */
pub struct StringSerializer<StringType>
where
    StringType: ToString + FromStr,
{
    pub extension: &'static str,
    _phantom: PhantomData<StringType>,
}
impl<StringType> StringSerializer<StringType>
where
    StringType: ToString + FromStr,
{
    /// Create a string serializer. The only argument is the name of the extension
    /// that the created files should have. For example:
    /// ```
    /// use fuzzcheck::StringSerializer;
    ///
    /// let ser = StringSerializer::<String>::new("txt");
    /// ````
    #[no_coverage]
    pub fn new(extension: &'static str) -> Self {
        Self {
            extension,
            _phantom: PhantomData,
        }
    }
}
impl<StringType> Serializer for StringSerializer<StringType>
where
    StringType: ToString + FromStr,
{
    type Value = StringType;

    #[no_coverage]
    fn extension(&self) -> &str {
        self.extension
    }
    #[no_coverage]
    fn from_data(&self, data: &[u8]) -> Option<Self::Value> {
        let string = String::from_utf8(data.to_vec()).ok()?;
        let value = Self::Value::from_str(&string).ok()?;
        Some(value)
    }
    #[no_coverage]
    fn to_data(&self, value: &Self::Value) -> Vec<u8> {
        value.to_string().into_bytes()
    }
}