1use serde;
4
5use self::serde::Deserialize;
6use chrono::{self, offset::FixedOffset, prelude::*};
7use hex::{self, FromHex, FromHexError};
8use std::{fmt, io};
9
10pub trait MyTryFromBytes: Sized {
12 type Err: 'static + Sized + ::std::error::Error;
13 fn try_from(_: &[u8]) -> Result<Self, Self::Err>;
14}
15
16pub fn from_base64<'d, T, D>(deserializer: D) -> Result<T, D::Error>
17where
18 D: serde::Deserializer<'d>,
19 T: MyTryFromBytes,
20{
21 use self::serde::de::Error;
22 String::deserialize(deserializer)
23 .and_then(|string| {
24 crate::base64_decode(&string).map_err(|err| Error::custom(err.to_string()))
25 })
26 .and_then(|ref bytes| {
27 <T as MyTryFromBytes>::try_from(bytes)
28 .map_err(|err| Error::custom(format!("{}", &err as &dyn (::std::error::Error))))
29 })
30}
31
32pub fn as_base64<T, S>(key: &T, serializer: S) -> Result<S::Ok, S::Error>
33where
34 T: AsRef<[u8]>,
35 S: serde::Serializer,
36{
37 serializer.serialize_str(&crate::base64_encode(key.as_ref()))
38}
39
40pub fn from_hex<'d, T, D>(deserializer: D) -> Result<T, D::Error>
41where
42 D: serde::Deserializer<'d>,
43 T: MyTryFromBytes,
44{
45 use self::serde::de::Error;
46 String::deserialize(deserializer)
47 .and_then(|string| {
48 FromHex::from_hex(string.as_str())
49 .map_err(|err: FromHexError| Error::custom(err.to_string()))
50 })
51 .and_then(|bytes: Vec<u8>| {
52 <T as MyTryFromBytes>::try_from(&bytes)
53 .map_err(|err| Error::custom(format!("{}", &err as &dyn (::std::error::Error))))
54 })
55}
56
57pub fn as_hex<T, S>(key: &T, serializer: S) -> Result<S::Ok, S::Error>
58where
59 T: AsRef<[u8]>,
60 S: serde::Serializer,
61{
62 serializer.serialize_str(&hex::encode(key))
63}
64
65pub fn from_rfc3339_fixed<'d, D>(deserializer: D) -> Result<chrono::DateTime<FixedOffset>, D::Error>
66where
67 D: serde::Deserializer<'d>,
68{
69 use self::serde::de::Error;
70 String::deserialize(deserializer)
71 .and_then(|string| {
72 DateTime::<FixedOffset>::parse_from_rfc3339(&string)
73 .map_err(|err| Error::custom(err.to_string()))
74 })
75 .map(|dt| dt.with_timezone(&dt.timezone()))
76}
77
78pub fn as_rfc3339_fixed<S>(
79 key: &chrono::DateTime<FixedOffset>,
80 serializer: S,
81) -> Result<S::Ok, S::Error>
82where
83 S: serde::Serializer,
84{
85 serializer.serialize_str(&key.to_rfc3339())
86}
87
88impl MyTryFromBytes for Vec<u8> {
89 type Err = io::Error;
90 fn try_from(slice: &[u8]) -> Result<Self, Self::Err> {
91 Ok(Vec::from(slice))
92 }
93}
94pub fn write_as_headerless_yaml<T: self::serde::Serialize>(
100 t: &T,
101 f: &mut dyn fmt::Write,
102) -> fmt::Result {
103 let s = serde_yaml::to_string(t).map_err(|_| fmt::Error)?;
104 f.write_str(&s)
105}