From f9bc5037f5a9be8e6711481d43df5406de324984 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 31 Jan 2017 01:23:14 +0100 Subject: [PATCH] Introduce ser::Impossible (fixes #694) --- serde/src/ser/impossible.rs | 170 ++++++++++++++++++++++++++++++++++++ serde/src/ser/mod.rs | 3 + 2 files changed, 173 insertions(+) create mode 100644 serde/src/ser/impossible.rs diff --git a/serde/src/ser/impossible.rs b/serde/src/ser/impossible.rs new file mode 100644 index 00000000..caa277cf --- /dev/null +++ b/serde/src/ser/impossible.rs @@ -0,0 +1,170 @@ +//! This module contains `Impossible` serializer and its implementations. + +use core::marker::PhantomData; + +use ser::{ + self, + Serialize, + SerializeSeq, + SerializeTuple, + SerializeTupleStruct, + SerializeTupleVariant, + SerializeMap, + SerializeStruct, + SerializeStructVariant, +}; + +/// The impossible serializer. +/// +/// This serializer cannot be instantiated, to be used in the associated types +/// of the `Serializer` trait, when implementing serializers that don't support +/// some constructs, like sequences or tuples. +/// +/// ```rust,ignore +/// impl Serializer for MySerializer { +/// type SerializeSeq = Impossible<(), Error>; +/// +/// fn serialize_seq(self, +/// len: Option) +/// -> Result { +/// // Given Impossible cannot be instantiated, the only +/// // thing we can do here is to return an error. +/// Err(...) +/// } +/// +/// ... +/// } +/// ``` +pub struct Impossible { + void: Void, + _marker: PhantomData<(Ok, E)>, +} + +enum Void {} + +impl SerializeSeq for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_element(&mut self, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeTuple for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_element(&mut self, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeTupleStruct for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_field(&mut self, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeTupleVariant for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_field(&mut self, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeMap for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_key(&mut self, + _key: &T) + -> Result<(), E> { + match self.void {} + } + + fn serialize_value(&mut self, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeStruct for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_field(&mut self, + _key: &'static str, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} + +impl SerializeStructVariant for Impossible + where E: ser::Error, +{ + type Ok = Ok; + type Error = E; + + fn serialize_field(&mut self, + _key: &'static str, + _value: &T) + -> Result<(), E> { + match self.void {} + } + + fn end(self) -> Result { + match self.void {} + } +} diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index af9880ef..3e97bd20 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -104,6 +104,9 @@ use core::cell::RefCell; use core::fmt::Display; mod impls; +mod impossible; + +pub use self::impossible::Impossible; ///////////////////////////////////////////////////////////////////////////////