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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use {
    byteorder::WriteBytesExt,
    serde::ser::{self, Serialize},
    std::{
        fmt::Display,
        io::{self, Write},
    },
};

pub use self::errors::{CompatSerializationError, Result, SerializationError};

/// Serializer for the XDR format.
///
/// Structure that holds a mutable borrow of the writer it serializes data to.
/// It has an implementation of `serde::Serializer` so that it can serialize
/// data into its XDR representation.
pub struct Serializer<'w, W>
where
    W: WriteBytesExt + 'w,
{
    writer: &'w mut W,
}

impl<'w, W> Serializer<'w, W>
where
    W: WriteBytesExt + 'w,
{
    /// Create a new instance that serializes data into the given generic
    /// writer.
    pub fn new(writer: &'w mut W) -> Self {
        Serializer { writer }
    }

    fn serialize_failure<T, S>(
        type_name: &str,
        value: T,
        error: S,
    ) -> CompatSerializationError
    where
        T: Display,
        S: Into<CompatSerializationError>,
    {
        SerializationError::Failure {
            what: format!("a value {} of type {}", value, type_name),
            cause: Box::new(error.into()),
        }
        .into()
    }

    fn serialize_opaque_failure<S>(
        length: usize,
        error: S,
    ) -> SerializationError
    where
        S: Into<CompatSerializationError>,
    {
        SerializationError::Failure {
            what: format!("opaque data of length {}", length),
            cause: Box::new(error.into()),
        }
    }

    fn io_error<T>(
        type_name: &str,
        value: T,
        error: io::Error,
    ) -> SerializationError
    where
        T: Display,
    {
        SerializationError::IoError {
            what: format!("a value {} of type {}", value, type_name),
            cause: error,
        }
    }

    fn serialize_opaque_io_error(
        length: usize,
        error: io::Error,
    ) -> SerializationError {
        SerializationError::IoError {
            what: format!("opaque data of length {}", length),
            cause: error,
        }
    }
}

mod serializer;

impl<'w, W> ser::SerializeMap for Serializer<'w, W>
where
    W: WriteBytesExt + 'w,
{
    type Ok = Self;
    type Error = CompatSerializationError;

    fn serialize_key<T>(&mut self, _key: &T) -> Result<()>
    where
        T: ?Sized + Serialize,
    {
        unreachable!("map is not supported")
    }

    fn serialize_value<T>(&mut self, _value: &T) -> Result<()>
    where
        T: ?Sized + Serialize,
    {
        unreachable!("map is not supported")
    }

    fn end(self) -> Result<Self> {
        unreachable!("map is not supported")
    }
}

/// Serialize data into a vector of bytes.
///
/// Serializes a generic data type into a new instance of `Vec<u8>`.
pub fn to_bytes<T>(value: &T) -> Result<Vec<u8>>
where
    T: Serialize,
{
    let mut bytes = Vec::new();

    value.serialize(Serializer::new(&mut bytes))?;

    Ok(bytes)
}

/// Serialize data through a generic writer.
///
/// Serializes a generic data type through a borrowed instance that implements
/// `Write`.
pub fn to_writer<W, T>(writer: &mut W, value: &T) -> Result<()>
where
    W: Write,
    T: Serialize,
{
    value.serialize(Serializer::new(writer))?;

    Ok(())
}

mod errors;