Skip to content

Commit

Permalink
Relocate some code, improve internals
Browse files Browse the repository at this point in the history
  • Loading branch information
jhpratt committed Mar 12, 2022
1 parent 40504b1 commit 5fde5ef
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 226 deletions.
36 changes: 0 additions & 36 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,42 +31,6 @@ pub use time_macros::date;
/// [`OffsetDateTime`]: crate::OffsetDateTime
/// [`PrimitiveDateTime`]: crate::PrimitiveDateTime
pub use time_macros::datetime;
/// Declares a custom format based on the provided string.
///
/// The syntax accepted by this macro is the same as [`format_description::parse()`], which can
/// be found in [the book](https://time-rs.github.io/book/api/format-description.html).
///
/// # Usage
///
/// Invoked as
/// `declare_format_string!(mod_name, Date, "<format string>")`: puts
/// a module named `mod_name` in the current namespace that can be used to
/// format `Date` structs.
///
/// # Examples
///
/// ```
/// # use time::OffsetDateTime;
/// # use time::macros::declare_format_string;
/// # use serde::{Serialize, Deserialize};
/// // Makes a module `mod my_format { ... }`.
/// declare_format_string!(my_format, OffsetDateTime, "hour=[hour], minute=[minute]");
///
/// #[derive(Serialize, Deserialize)]
/// struct SerializesWithCustom {
/// #[serde(with = "my_format")]
/// dt: OffsetDateTime,
/// #[serde(with = "my_format::option")]
/// maybe_dt: Option<OffsetDateTime>,
/// }
/// #
/// # // otherwise rustdoc tests don't work because we put a module in `main()`
/// # fn main() {}
/// ```
///
/// [`format_description::parse()`]: crate::format_description::parse()
#[cfg(feature = "serde-human-readable")]
pub use time_macros::declare_format_string;
/// Equivalent of performing [`format_description::parse()`] at compile time.
///
/// Using the macro instead of the function results in a static slice rather than a [`Vec`],
Expand Down
37 changes: 37 additions & 0 deletions src/serde/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,43 @@ use core::marker::PhantomData;
#[cfg(feature = "serde-human-readable")]
use serde::ser::Error as _;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// Generate a custom serializer and deserializer from the provided string.
///
/// The syntax accepted by this macro is the same as [`format_description::parse()`], which can
/// be found in [the book](https://time-rs.github.io/book/api/format-description.html).
///
/// # Usage
///
/// Invoked as `serde::format_description!(mod_name, Date, "<format string>")`. This puts a
/// module named `mod_name` in the current scope that can be used to format `Date` structs. A
/// submodule (`mod_name::option`) is also generated for `Option<Date>`. Both modules are only
/// visible in the current scope.
///
/// # Examples
///
/// ```
/// # use time::OffsetDateTime;
/// # use ::serde::{Serialize, Deserialize};
/// use time::serde;
///
/// // Makes a module `mod my_format { ... }`.
/// serde::format_description!(my_format, OffsetDateTime, "hour=[hour], minute=[minute]");
///
/// #[derive(Serialize, Deserialize)]
/// struct SerializesWithCustom {
/// #[serde(with = "my_format")]
/// dt: OffsetDateTime,
/// #[serde(with = "my_format::option")]
/// maybe_dt: Option<OffsetDateTime>,
/// }
/// #
/// # // otherwise rustdoc tests don't work because we put a module in `main()`
/// # fn main() {}
/// ```
///
/// [`format_description::parse()`]: crate::format_description::parse()
#[cfg(all(feature = "macros", feature = "serde-human-readable"))]
pub use time_macros::serde_format_description as format_description;

use self::visitor::Visitor;
#[cfg(feature = "parsing")]
Expand Down
26 changes: 13 additions & 13 deletions tests/integration/compile-fail/invalid_serializer.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use time::macros::declare_format_string;
use time::serde;

declare_format_string!(); // unexpected end of input
declare_format_string!("bad string", OffsetDateTime, "[year] [month]"); // module name is not ident
declare_format_string!(my_format: OffsetDateTime, "[year] [month]"); // not a comma
declare_format_string!(my_format,); // missing formattable and string
declare_format_string!(my_format, "[year] [month]"); // missing formattable
declare_format_string!(OffsetDateTime, "[year] [month]"); // missing ident
declare_format_string!(my_format, OffsetDateTime); // missing string format
declare_format_string!(my_format, OffsetDateTime,); // missing string format
declare_format_string!(my_format, OffsetDateTime "[year] [month]"); // missing comma
declare_format_string!(my_format, OffsetDateTime : "[year] [month]"); // not a comma
declare_format_string!(my_format, OffsetDateTime, "[bad]"); // bad component name
declare_format_string!(my_format, OffsetDateTime, not_string); // string format wrong type
serde::format_description!(); // unexpected end of input
serde::format_description!("bad string", OffsetDateTime, "[year] [month]"); // module name is not ident
serde::format_description!(my_format: OffsetDateTime, "[year] [month]"); // not a comma
serde::format_description!(my_format,); // missing formattable and string
serde::format_description!(my_format, "[year] [month]"); // missing formattable
serde::format_description!(OffsetDateTime, "[year] [month]"); // missing ident
serde::format_description!(my_format, OffsetDateTime); // missing string format
serde::format_description!(my_format, OffsetDateTime,); // missing string format
serde::format_description!(my_format, OffsetDateTime "[year] [month]"); // missing comma
serde::format_description!(my_format, OffsetDateTime : "[year] [month]"); // not a comma
serde::format_description!(my_format, OffsetDateTime, "[bad]"); // bad component name
serde::format_description!(my_format, OffsetDateTime, not_string); // string format wrong type

fn main() {}
72 changes: 36 additions & 36 deletions tests/integration/compile-fail/invalid_serializer.stderr
Original file line number Diff line number Diff line change
@@ -1,79 +1,79 @@
error: unexpected end of input
--> $DIR/invalid_serializer.rs:3:1
|
3 | declare_format_string!(); // unexpected end of input
| ^^^^^^^^^^^^^^^^^^^^^^^^
3 | serde::format_description!(); // unexpected end of input
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `declare_format_string` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `serde::format_description` (in Nightly builds, run with -Z macro-backtrace for more info)

error: unexpected token: "bad string"
--> $DIR/invalid_serializer.rs:4:24
--> $DIR/invalid_serializer.rs:4:28
|
4 | declare_format_string!("bad string", OffsetDateTime, "[year] [month]"); // module name is not ident
| ^^^^^^^^^^^^
4 | serde::format_description!("bad string", OffsetDateTime, "[year] [month]"); // module name is not ident
| ^^^^^^^^^^^^

error: unexpected token: :
--> $DIR/invalid_serializer.rs:5:33
--> $DIR/invalid_serializer.rs:5:37
|
5 | declare_format_string!(my_format: OffsetDateTime, "[year] [month]"); // not a comma
| ^
5 | serde::format_description!(my_format: OffsetDateTime, "[year] [month]"); // not a comma
| ^

error: unexpected end of input
--> $DIR/invalid_serializer.rs:6:1
|
6 | declare_format_string!(my_format,); // missing formattable and string
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6 | serde::format_description!(my_format,); // missing formattable and string
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `declare_format_string` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `serde::format_description` (in Nightly builds, run with -Z macro-backtrace for more info)

error: unexpected token: "[year] [month]"
--> $DIR/invalid_serializer.rs:7:35
--> $DIR/invalid_serializer.rs:7:39
|
7 | declare_format_string!(my_format, "[year] [month]"); // missing formattable
| ^^^^^^^^^^^^^^^^
7 | serde::format_description!(my_format, "[year] [month]"); // missing formattable
| ^^^^^^^^^^^^^^^^

error: unexpected token: "[year] [month]"
--> $DIR/invalid_serializer.rs:8:40
--> $DIR/invalid_serializer.rs:8:44
|
8 | declare_format_string!(OffsetDateTime, "[year] [month]"); // missing ident
| ^^^^^^^^^^^^^^^^
8 | serde::format_description!(OffsetDateTime, "[year] [month]"); // missing ident
| ^^^^^^^^^^^^^^^^

error: unexpected end of input
--> $DIR/invalid_serializer.rs:9:1
|
9 | declare_format_string!(my_format, OffsetDateTime); // missing string format
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9 | serde::format_description!(my_format, OffsetDateTime); // missing string format
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `declare_format_string` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `serde::format_description` (in Nightly builds, run with -Z macro-backtrace for more info)

error: expected string
--> $DIR/invalid_serializer.rs:10:1
|
10 | declare_format_string!(my_format, OffsetDateTime,); // missing string format
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
10 | serde::format_description!(my_format, OffsetDateTime,); // missing string format
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `declare_format_string` (in Nightly builds, run with -Z macro-backtrace for more info)
= note: this error originates in the macro `serde::format_description` (in Nightly builds, run with -Z macro-backtrace for more info)

error: unexpected token: "[year] [month]"
--> $DIR/invalid_serializer.rs:11:50
--> $DIR/invalid_serializer.rs:11:54
|
11 | declare_format_string!(my_format, OffsetDateTime "[year] [month]"); // missing comma
| ^^^^^^^^^^^^^^^^
11 | serde::format_description!(my_format, OffsetDateTime "[year] [month]"); // missing comma
| ^^^^^^^^^^^^^^^^

error: unexpected token: :
--> $DIR/invalid_serializer.rs:12:50
--> $DIR/invalid_serializer.rs:12:54
|
12 | declare_format_string!(my_format, OffsetDateTime : "[year] [month]"); // not a comma
| ^
12 | serde::format_description!(my_format, OffsetDateTime : "[year] [month]"); // not a comma
| ^

error: invalid component name `bad` at byte index 1
--> $DIR/invalid_serializer.rs:13:51
--> $DIR/invalid_serializer.rs:13:55
|
13 | declare_format_string!(my_format, OffsetDateTime, "[bad]"); // bad component name
| ^^^^^^^
13 | serde::format_description!(my_format, OffsetDateTime, "[bad]"); // bad component name
| ^^^^^^^

error: expected string
--> $DIR/invalid_serializer.rs:14:51
--> $DIR/invalid_serializer.rs:14:55
|
14 | declare_format_string!(my_format, OffsetDateTime, not_string); // string format wrong type
| ^^^^^^^^^^
14 | serde::format_description!(my_format, OffsetDateTime, not_string); // string format wrong type
| ^^^^^^^^^^
25 changes: 10 additions & 15 deletions tests/integration/serde/macros.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,23 @@
use serde::{Deserialize, Serialize};
use ::serde::{Deserialize, Serialize};
use serde_test::{
assert_de_tokens_error, assert_ser_tokens_error, assert_tokens, Configure, Token,
};
use time::macros::{date, datetime, declare_format_string, offset};
use time::{Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
use time::macros::{date, datetime, offset};
use time::{serde, Date, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};

declare_format_string!(
serde::format_description!(
offset_dt_format,
OffsetDateTime,
"custom format: [year]-[month]-[day] [hour]:[minute]:[second] [offset_hour]:[offset_minute]"
);

declare_format_string!(
serde::format_description!(
primitive_dt_format,
PrimitiveDateTime,
"custom format: [year]-[month]-[day] [hour]:[minute]:[second]"
);

declare_format_string!(time_format, Time, "custom format: [minute]:[second]");

declare_format_string!(date_format, Date, "custom format: [year]-[month]-[day]");

declare_format_string!(
serde::format_description!(time_format, Time, "custom format: [minute]:[second]");
serde::format_description!(date_format, Date, "custom format: [year]-[month]-[day]");
serde::format_description!(
offset_format,
UtcOffset,
"custom format: [offset_hour]:[offset_minute]"
Expand Down Expand Up @@ -131,9 +127,8 @@ fn custom_serialize_error() {
);
}

// This format string has offset_hour and offset_minute, but is for formatting
// PrimitiveDateTime.
declare_format_string!(
// This format string has offset_hour and offset_minute, but is for formatting PrimitiveDateTime.
serde::format_description!(
primitive_date_time_format_bad,
PrimitiveDateTime,
"[offset_hour]:[offset_minute]"
Expand Down
Loading

0 comments on commit 5fde5ef

Please sign in to comment.