use crate::{Error, Result};
use serde::ser::Impossible;
use serde::ser::Serialize;
use impl_serialize::impl_serialize;
pub struct MapKeySerializer;
impl serde::Serializer for MapKeySerializer {
type Ok = String;
type Error = Error;
type SerializeSeq = Impossible<String, Error>;
type SerializeTuple = Impossible<String, Error>;
type SerializeTupleStruct = Impossible<String, Error>;
type SerializeTupleVariant = Impossible<String, Error>;
type SerializeMap = Impossible<String, Error>;
type SerializeStruct = Impossible<String, Error>;
type SerializeStructVariant = Impossible<String, Error>;
#[inline]
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<String> {
Ok(variant.to_owned())
}
#[inline]
fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<String>
where
T: ?Sized + Serialize,
{
value.serialize(self)
}
#[inline]
fn serialize_char(self, value: char) -> Result<String> {
Ok({
let mut s = String::new();
s.push(value);
s
})
}
#[inline]
fn serialize_str(self, value: &str) -> Result<String> {
Ok(value.to_owned())
}
fn collect_str<T>(self, value: &T) -> Result<String>
where
T: ?Sized + std::fmt::Display,
{
Ok(value.to_string())
}
impl_serialize!(Ok(v.to_string()), [
i8, i16, i32, i64,
u8, u16, u32, u64
]);
impl_serialize!(Err(Error::KeyMustBeAString), [
bool, f32, f64,
bytes,
unit, unit_struct,
newtype_variant,
none, some,
seq, map,
tuple, tuple_struct, tuple_variant,
struct, struct_variant
]);
}
#[cfg(test)]
mod tests {
use serde::Serialize;
use super::*;
#[test]
fn str() {
let input_str = "bar";
let result = input_str.serialize(MapKeySerializer).unwrap();
assert_eq!(result, String::from("bar"));
}
#[test]
fn char() {
let input_char = 'c';
let result = input_char.serialize(MapKeySerializer).unwrap();
assert_eq!(result, String::from("c"));
}
#[test]
fn newtype_struct() {
#[derive(Serialize)]
struct NewType(char);
let newtype_struct = NewType('g');
let result = newtype_struct.serialize(MapKeySerializer).unwrap();
assert_eq!(result, String::from("g"));
}
}