Skip to content

Commit

Permalink
Merge #513
Browse files Browse the repository at this point in the history
513: Avoid absolut import in macros and always import through the `serde_with` crate r=jonasbb a=jonasbb

Instead import names through the `serde_with` crate.
This should make the code more portable by avoiding references to std.
The `macro` feature still depends on `std`, but this might be removable
in the future.

Co-authored-by: Jonas Bushart <jonas@bushart.org>
  • Loading branch information
bors[bot] and jonasbb authored Sep 8, 2022
2 parents 97f9aea + 7abb244 commit 9454ca7
Show file tree
Hide file tree
Showing 24 changed files with 471 additions and 576 deletions.
10 changes: 10 additions & 0 deletions serde_with/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ name = "derives"
path = "tests/derives/lib.rs"
required-features = ["macros"]

[[test]]
name = "with_prefix"
path = "tests/with_prefix.rs"
required-features = ["macros"]

[[test]]
name = "rust"
path = "tests/rust.rs"
required-features = ["alloc"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
Expand Down
57 changes: 26 additions & 31 deletions serde_with/src/base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@
//!
//! Please check the documentation on the [`Base64`] type for details.

use crate::{formats, DeserializeAs, SerializeAs};
use alloc::vec::Vec;
use base64::Config;
use core::{
convert::{TryFrom, TryInto},
fmt,
marker::PhantomData,
};
use serde::{de::Error, Deserializer, Serialize, Serializer};
use crate::prelude::*;

/// Serialize bytes with base64
///
Expand Down Expand Up @@ -83,7 +75,7 @@ where
where
S: Serializer,
{
base64::encode_config(source, base64::Config::new(CHARSET::charset(), true))
::base64::encode_config(source, ::base64::Config::new(CHARSET::charset(), true))
.serialize(serializer)
}
}
Expand All @@ -97,7 +89,7 @@ where
where
S: Serializer,
{
base64::encode_config(source, base64::Config::new(CHARSET::charset(), false))
::base64::encode_config(source, ::base64::Config::new(CHARSET::charset(), false))
.serialize(serializer)
}
}
Expand All @@ -112,9 +104,9 @@ where
where
D: Deserializer<'de>,
{
struct Visitor<T, CHARSET>(PhantomData<(T, CHARSET)>);
struct Helper<T, CHARSET>(PhantomData<(T, CHARSET)>);

impl<'de, T, CHARSET> serde::de::Visitor<'de> for Visitor<T, CHARSET>
impl<'de, T, CHARSET> Visitor<'de> for Helper<T, CHARSET>
where
T: TryFrom<Vec<u8>>,
CHARSET: CharacterSet,
Expand All @@ -127,22 +119,25 @@ where

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let bytes = base64::decode_config(value, Config::new(CHARSET::charset(), false))
.map_err(Error::custom)?;
let bytes = ::base64::decode_config(
value,
::base64::Config::new(CHARSET::charset(), false),
)
.map_err(DeError::custom)?;

let length = bytes.len();
bytes.try_into().map_err(|_e: T::Error| {
Error::custom(format_args!(
DeError::custom(format_args!(
"Can't convert a Byte Vector of length {} to the output type.",
length
))
})
}
}

deserializer.deserialize_str(Visitor::<T, CHARSET>(PhantomData))
deserializer.deserialize_str(Helper::<T, CHARSET>(PhantomData))
}
}

Expand All @@ -151,16 +146,16 @@ pub trait CharacterSet {
/// Return a specific character set.
///
/// Return one enum variant of the [`base64::CharacterSet`](base64::CharacterSet) enum.
fn charset() -> base64::CharacterSet;
fn charset() -> ::base64::CharacterSet;
}

/// The standard character set (uses `+` and `/`).
///
/// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
pub struct Standard;
impl CharacterSet for Standard {
fn charset() -> base64::CharacterSet {
base64::CharacterSet::Standard
fn charset() -> ::base64::CharacterSet {
::base64::CharacterSet::Standard
}
}

Expand All @@ -169,8 +164,8 @@ impl CharacterSet for Standard {
/// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
pub struct UrlSafe;
impl CharacterSet for UrlSafe {
fn charset() -> base64::CharacterSet {
base64::CharacterSet::UrlSafe
fn charset() -> ::base64::CharacterSet {
::base64::CharacterSet::UrlSafe
}
}

Expand All @@ -179,16 +174,16 @@ impl CharacterSet for UrlSafe {
/// Not standardized, but folk wisdom on the net asserts that this alphabet is what crypt uses.
pub struct Crypt;
impl CharacterSet for Crypt {
fn charset() -> base64::CharacterSet {
base64::CharacterSet::Crypt
fn charset() -> ::base64::CharacterSet {
::base64::CharacterSet::Crypt
}
}

/// The bcrypt character set (uses `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`).
pub struct Bcrypt;
impl CharacterSet for Bcrypt {
fn charset() -> base64::CharacterSet {
base64::CharacterSet::Bcrypt
fn charset() -> ::base64::CharacterSet {
::base64::CharacterSet::Bcrypt
}
}

Expand All @@ -197,8 +192,8 @@ impl CharacterSet for Bcrypt {
/// See [RFC 3501](https://tools.ietf.org/html/rfc3501#section-5.1.3).
pub struct ImapMutf7;
impl CharacterSet for ImapMutf7 {
fn charset() -> base64::CharacterSet {
base64::CharacterSet::ImapMutf7
fn charset() -> ::base64::CharacterSet {
::base64::CharacterSet::ImapMutf7
}
}

Expand All @@ -207,7 +202,7 @@ impl CharacterSet for ImapMutf7 {
/// See [BinHex 4.0 Definition](http://files.stairways.com/other/binhex-40-specs-info.txt).
pub struct BinHex;
impl CharacterSet for BinHex {
fn charset() -> base64::CharacterSet {
base64::CharacterSet::BinHex
fn charset() -> ::base64::CharacterSet {
::base64::CharacterSet::BinHex
}
}
52 changes: 18 additions & 34 deletions serde_with/src/chrono_0_4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,12 @@
//! [chrono]: https://docs.rs/chrono/

use crate::{
de::DeserializeAs,
formats::{Flexible, Format, Strict, Strictness},
ser::SerializeAs,
utils::duration::{DurationSigned, Sign},
DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds, TimestampMicroSecondsWithFrac,
TimestampMilliSeconds, TimestampMilliSecondsWithFrac, TimestampNanoSeconds,
TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
prelude::*,
};
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "std")]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use chrono_0_4::Local;
use chrono_0_4::{DateTime, Duration, NaiveDateTime, TimeZone, Utc};
#[cfg(feature = "std")]
use core::fmt;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use ::chrono_0_4::Local;
use ::chrono_0_4::{DateTime, Duration, NaiveDateTime, TimeZone, Utc};

/// Create a [`DateTime`] for the Unix Epoch using the [`Utc`] timezone
fn unix_epoch_utc() -> DateTime<Utc> {
Expand Down Expand Up @@ -69,8 +55,6 @@ fn unix_epoch_naive() -> NaiveDateTime {
#[cfg(feature = "std")]
pub mod datetime_utc_ts_seconds_from_any {
use super::*;
use chrono_0_4::{DateTime, NaiveDateTime, Utc};
use serde::de::{Deserializer, Error, Unexpected, Visitor};

/// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
Expand All @@ -88,13 +72,13 @@ pub mod datetime_utc_ts_seconds_from_any {

fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let ndt = NaiveDateTime::from_timestamp_opt(value, 0);
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format_args!(
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
)))
Expand All @@ -103,13 +87,13 @@ pub mod datetime_utc_ts_seconds_from_any {

fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let ndt = NaiveDateTime::from_timestamp_opt(value as i64, 0);
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format_args!(
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
)))
Expand All @@ -118,15 +102,15 @@ pub mod datetime_utc_ts_seconds_from_any {

fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let seconds = value.trunc() as i64;
let nsecs = (value.fract() * 1_000_000_000_f64).abs() as u32;
let ndt = NaiveDateTime::from_timestamp_opt(seconds, nsecs);
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format_args!(
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
)))
Expand All @@ -135,7 +119,7 @@ pub mod datetime_utc_ts_seconds_from_any {

fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
E: DeError,
{
let parts: Vec<_> = value.split('.').collect();

Expand All @@ -146,20 +130,20 @@ pub mod datetime_utc_ts_seconds_from_any {
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format_args!(
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
)))
}
} else {
Err(Error::invalid_value(Unexpected::Str(value), &self))
Err(DeError::invalid_value(Unexpected::Str(value), &self))
}
}
[seconds, subseconds] => {
if let Ok(seconds) = seconds.parse() {
let subseclen = subseconds.chars().count() as u32;
if subseclen > 9 {
return Err(Error::custom(format_args!(
return Err(DeError::custom(format_args!(
"DateTimes only support nanosecond precision but '{}' has more than 9 digits.",
value
)));
Expand All @@ -172,20 +156,20 @@ pub mod datetime_utc_ts_seconds_from_any {
if let Some(ndt) = ndt {
Ok(DateTime::<Utc>::from_utc(ndt, Utc))
} else {
Err(Error::custom(format_args!(
Err(DeError::custom(format_args!(
"a timestamp which can be represented in a DateTime but received '{}'",
value
)))
}
} else {
Err(Error::invalid_value(Unexpected::Str(value), &self))
Err(DeError::invalid_value(Unexpected::Str(value), &self))
}
} else {
Err(Error::invalid_value(Unexpected::Str(value), &self))
Err(DeError::invalid_value(Unexpected::Str(value), &self))
}
}

_ => Err(Error::invalid_value(Unexpected::Str(value), &self)),
_ => Err(DeError::invalid_value(Unexpected::Str(value), &self)),
}
}
}
Expand Down Expand Up @@ -235,7 +219,7 @@ where
let mut chrono_dur = match Duration::from_std(dur.duration) {
Ok(dur) => dur,
Err(msg) => {
return Err(de::Error::custom(format_args!(
return Err(DeError::custom(format_args!(
"Duration is outside of the representable range: {}",
msg
)))
Expand Down
Loading

0 comments on commit 9454ca7

Please sign in to comment.