#![cfg_attr(docsrs, feature(doc_cfg))]
use proc_macro::TokenStream;
use quote::quote;
use syn::{LitStr, parse_macro_input};
#[cfg(feature = "humantime")]
mod duration;
#[cfg_attr(docsrs, doc(cfg(feature = "humantime")))]
#[cfg(feature = "humantime")]
#[proc_macro]
pub fn duration(input: TokenStream) -> TokenStream {
use crate::duration::DurationMacroInput;
let DurationMacroInput { duration, scalar } = parse_macro_input!(input);
match humantime::parse_duration(&duration.value()) {
Ok(duration) => {
let duration = duration.mul_f64(scalar);
let seconds = duration.as_secs();
let nanoseconds = duration.subsec_nanos();
quote! {
::std::time::Duration::new(#seconds, #nanoseconds)
}
.into()
}
Err(error) => syn::Error::new(
duration.span(),
format!("failed to parse string as Duration: {error}"),
)
.to_compile_error()
.into(),
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "humantime")))]
#[cfg(feature = "humantime")]
#[proc_macro]
pub fn datetime(input: TokenStream) -> TokenStream {
let literal: LitStr = parse_macro_input!(input);
let string = literal.value();
match humantime::parse_rfc3339_weak(&string) {
Ok(datetime) => {
use std::time::UNIX_EPOCH;
let duration = datetime.duration_since(UNIX_EPOCH).unwrap();
let seconds = duration.as_secs();
let nanoseconds = duration.subsec_nanos();
quote! {
::std::time::SystemTime::UNIX_EPOCH + ::std::time::Duration::new(#seconds, #nanoseconds)
}
.into()
}
Err(error) => syn::Error::new(
literal.span(),
format!("failed to parse string as SystemTime: {error}"),
)
.to_compile_error()
.into(),
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "bytesize")))]
#[cfg(feature = "bytesize")]
#[proc_macro]
pub fn bytes(input: TokenStream) -> TokenStream {
let literal: LitStr = parse_macro_input!(input);
let string = literal.value();
match string.parse::<bytesize::ByteSize>() {
Ok(size) => {
let bytes = size.as_u64();
quote! {
#bytes
}
.into()
}
Err(error) => syn::Error::new(
literal.span(),
format!("failed to parse string as byte size: {error}"),
)
.to_compile_error()
.into(),
}
}