fuzzcheck/serializers/
mod.rs

1//! Types implementing the [Serializer] trait.
2//!
3//! There are currently three implementations:
4//!
5//! * SerdeSerializer uses the `serde` and `serde_json` crate to serialize
6//! the test inputs (of arbitrary Serializable type) to a `.json` file.
7//!
8//! * [ByteSerializer] encodes and decodes values of type `Vec<u8>` by simply
9//! copy/pasting the bytes from/to the files. The extension is customizable.
10//!
11//! * [StringSerializer] encodes and decodes values of any type implementing
12//! `FromStr` and `ToString` into utf-8 encoded text files.
13
14#[cfg(feature = "serde_ron_serializer")]
15mod serde_ron_serializer;
16#[cfg(feature = "serde_json_serializer")]
17mod serde_serializer;
18
19use std::marker::PhantomData;
20use std::str::FromStr;
21
22#[cfg(feature = "serde_ron_serializer")]
23pub use serde_ron_serializer::SerdeRonSerializer;
24#[cfg(feature = "serde_json_serializer")]
25pub use serde_serializer::SerdeSerializer;
26
27use crate::Serializer;
28
29/**
30A Serializer for `Vec<u8>` that simply copies the bytes from/to the files.
31*/
32pub struct ByteSerializer {
33    ext: &'static str,
34}
35
36impl ByteSerializer {
37    /// Create a byte serializer. The only argument is the name of the extension
38    /// that the created files should have. For example:
39    /// ```
40    /// use fuzzcheck::ByteSerializer;
41    ///
42    /// let ser = ByteSerializer::new("png");
43    /// ````
44    #[coverage(off)]
45    pub fn new(ext: &'static str) -> Self {
46        Self { ext }
47    }
48}
49
50impl crate::traits::Serializer for ByteSerializer {
51    type Value = Vec<u8>;
52
53    #[coverage(off)]
54    fn extension(&self) -> &str {
55        self.ext
56    }
57    #[coverage(off)]
58    fn from_data(&self, data: &[u8]) -> Option<Self::Value> {
59        Some(data.into())
60    }
61    #[coverage(off)]
62    fn to_data(&self, value: &Self::Value) -> Vec<u8> {
63        value.clone()
64    }
65}
66
67/**
68A serializer that encodes and decodes values of any type implementing
69`FromStr` and `ToString` into utf-8 encoded text files.
70 */
71pub struct StringSerializer<StringType>
72where
73    StringType: ToString + FromStr,
74{
75    pub extension: &'static str,
76    _phantom: PhantomData<StringType>,
77}
78impl<StringType> StringSerializer<StringType>
79where
80    StringType: ToString + FromStr,
81{
82    /// Create a string serializer. The only argument is the name of the extension
83    /// that the created files should have. For example:
84    /// ```
85    /// use fuzzcheck::StringSerializer;
86    ///
87    /// let ser = StringSerializer::<String>::new("txt");
88    /// ````
89    #[coverage(off)]
90    pub fn new(extension: &'static str) -> Self {
91        Self {
92            extension,
93            _phantom: PhantomData,
94        }
95    }
96}
97impl<StringType> Serializer for StringSerializer<StringType>
98where
99    StringType: ToString + FromStr,
100{
101    type Value = StringType;
102
103    #[coverage(off)]
104    fn extension(&self) -> &str {
105        self.extension
106    }
107    #[coverage(off)]
108    fn from_data(&self, data: &[u8]) -> Option<Self::Value> {
109        let string = String::from_utf8(data.to_vec()).ok()?;
110        let value = Self::Value::from_str(&string).ok()?;
111        Some(value)
112    }
113    #[coverage(off)]
114    fn to_data(&self, value: &Self::Value) -> Vec<u8> {
115        value.to_string().into_bytes()
116    }
117}