I don't know about Rust. Several people responded that Java already has a builder interface for creating a format string. That is possibly more type erased than the Rust macro equivalent. In C++ I would use variadic templates, as I originally proposed in my root comment: `format(year(), '/', ...)`.
The format_description! macro uses the same syntax as the format_description::parse method. If you want to support user-provided formatting strings (which you do), then you need such a method already, and once you’ve got that, why do the macro differently?
That components have parameters makes the non-literal approach even less compelling: take this which can produce the likes of “2:34:56pm”:
You could easily provide a prettier DSL so that you could write something like this:
use time::format_description::shorthand::{HOUR, MINUTE, SECOND, PERIOD, literal};
[
HOUR.padding_none().repr_12(),
literal(":"),
MINUTE,
":".into(), // even this if you wanted
SECOND,
PERIOD.case_lower(),
]
This wouldn’t be awful in the absence of the parse method, but really, once you have that, the format_description macro is just what you want: compact, checked at compile time, and matching a runtime equivalent which can take user-provided format strings.
(Now there are two or three changes I’d prefer to make to format_description’s syntax: I’d use = instead of :, the two being generally very similar but : far more regularly occurring in literal parts, so that the different = would make it scan better; and I think that escaping opening square brackets by doubling them but not requiring doubling for closing square brackets was a particularly bad idea; and I’m mildly inclined to prefer {} to []. So I might end up with "{hour padding=none repr=12}:{minute}:{second}{period case=lower}".)
I don’t think the language has anything suitable for these purposes. What did you have in mind?