Skip to main content

time_macros/format_description/public/
mod.rs

1mod component;
2pub(super) mod modifier;
3mod optimizing;
4
5use proc_macro::TokenStream;
6
7pub(crate) use self::component::Component;
8use crate::FormatDescriptionVersion;
9use crate::to_tokens::ToTokenStream;
10
11#[derive(#[automatically_derived]
impl ::core::clone::Clone for OwnedFormatItem {
    #[inline]
    fn clone(&self) -> OwnedFormatItem {
        OwnedFormatItem {
            version: ::core::clone::Clone::clone(&self.version),
            inner: ::core::clone::Clone::clone(&self.inner),
        }
    }
}Clone)]
12pub(crate) struct OwnedFormatItem {
13    pub(crate) version: FormatDescriptionVersion,
14    pub(crate) inner: OwnedFormatItemInner,
15}
16
17#[derive(#[automatically_derived]
impl ::core::clone::Clone for OwnedFormatItemInner {
    #[inline]
    fn clone(&self) -> OwnedFormatItemInner {
        match self {
            OwnedFormatItemInner::Literal(__self_0) =>
                OwnedFormatItemInner::Literal(::core::clone::Clone::clone(__self_0)),
            OwnedFormatItemInner::StringLiteral(__self_0) =>
                OwnedFormatItemInner::StringLiteral(::core::clone::Clone::clone(__self_0)),
            OwnedFormatItemInner::Component(__self_0) =>
                OwnedFormatItemInner::Component(::core::clone::Clone::clone(__self_0)),
            OwnedFormatItemInner::Compound(__self_0) =>
                OwnedFormatItemInner::Compound(::core::clone::Clone::clone(__self_0)),
            OwnedFormatItemInner::Optional { format: __self_0, item: __self_1
                } =>
                OwnedFormatItemInner::Optional {
                    format: ::core::clone::Clone::clone(__self_0),
                    item: ::core::clone::Clone::clone(__self_1),
                },
            OwnedFormatItemInner::First(__self_0) =>
                OwnedFormatItemInner::First(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone)]
18pub(crate) enum OwnedFormatItemInner {
19    Literal(Vec<u8>),
20    StringLiteral(String),
21    Component(Component),
22    Compound(Vec<Self>),
23    Optional { format: bool, item: Box<Self> },
24    First(Vec<Self>),
25}
26
27impl ToTokenStream for OwnedFormatItem {
28    fn append_to(self, ts: &mut TokenStream) {
29        match self.version {
30            FormatDescriptionVersion::V1 | FormatDescriptionVersion::V2 => match self.inner {
31                OwnedFormatItemInner::Literal(bytes) => {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFormatItem",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"Literal", Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([crate::to_tokens::ToTokenTree::into_token_tree(Literal::byte_string(bytes.as_ref()))]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
32                    BorrowedFormatItem::Literal(#(Literal::byte_string(bytes.as_ref())))
33                },
34                OwnedFormatItemInner::StringLiteral(string) => {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFormatItem",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"StringLiteral",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([crate::to_tokens::ToTokenTree::into_token_tree(string.as_ref())]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
35                    BorrowedFormatItem::StringLiteral(#(string.as_ref()))
36                },
37                OwnedFormatItemInner::Component(component) => {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFormatItem",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"Component",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Literal::usize_unsuffixed(0))]);
                            ts_mut.extend([TokenTree::from(Punct::new(':',
                                                Spacing::Alone))]);
                            ;
                            crate::to_tokens::ToTokenStream::append_to(component,
                                ts_mut);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
38                    BorrowedFormatItem::Component { 0: #S(component) }
39                },
40                OwnedFormatItemInner::Compound(items) => {
41                    let items = items
42                        .into_iter()
43                        .map(|item| {
44                            {
    use proc_macro::*;
    let mut ts = TokenStream::new();
    let ts_mut = &mut ts;
    crate::to_tokens::ToTokenStream::append_to(Self {
            version: self.version,
            inner: item,
        }, ts_mut);
    ts_mut.extend([TokenTree::from(Punct::new(',', Spacing::Alone))]);
    ;
    ;
    ts
}quote_! { #S(Self { version: self.version, inner: item }), }
45                        })
46                        .collect::<TokenStream>();
47                    {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFormatItem",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"Compound", Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Literal::usize_unsuffixed(0))]);
                            ts_mut.extend([TokenTree::from(Punct::new(':',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::from(Punct::new('&',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Bracket,
                                                {
                                                    use proc_macro::*;
                                                    let mut ts = TokenStream::new();
                                                    let ts_mut = &mut ts;
                                                    crate::to_tokens::ToTokenStream::append_to(items, ts_mut);
                                                    ;
                                                    ts
                                                }))]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
48                        BorrowedFormatItem::Compound { 0: &[#S(items)] }
49                    }
50                }
51                OwnedFormatItemInner::Optional { format, item } => {
52                    if !format {
53                        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("internal error: v1 and v2 format descriptions must format optional items")));
}bug!("v1 and v2 format descriptions must format optional items")
54                    }
55                    {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFormatItem",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"Optional", Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Literal::usize_unsuffixed(0))]);
                            ts_mut.extend([TokenTree::from(Punct::new(':',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::from(Punct::new('&',
                                                Spacing::Alone))]);
                            ;
                            crate::to_tokens::ToTokenStream::append_to(Self {
                                    version: self.version,
                                    inner: *item,
                                }, ts_mut);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
56                        BorrowedFormatItem::Optional {
57                            0: &#S(Self { version: self.version, inner: *item })
58                        }
59                    }
60                }
61                OwnedFormatItemInner::First(items) => {
62                    let items = items
63                        .into_iter()
64                        .map(|item| {
65                            {
    use proc_macro::*;
    let mut ts = TokenStream::new();
    let ts_mut = &mut ts;
    crate::to_tokens::ToTokenStream::append_to(Self {
            version: self.version,
            inner: item,
        }, ts_mut);
    ts_mut.extend([TokenTree::from(Punct::new(',', Spacing::Alone))]);
    ;
    ;
    ts
}quote_! { #S(Self { version: self.version, inner: item }), }
66                        })
67                        .collect::<TokenStream>();
68                    {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFormatItem",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"First", Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Literal::usize_unsuffixed(0))]);
                            ts_mut.extend([TokenTree::from(Punct::new(':',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::from(Punct::new('&',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Bracket,
                                                {
                                                    use proc_macro::*;
                                                    let mut ts = TokenStream::new();
                                                    let ts_mut = &mut ts;
                                                    crate::to_tokens::ToTokenStream::append_to(items, ts_mut);
                                                    ;
                                                    ts
                                                }))]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
69                        BorrowedFormatItem::First { 0: &[#S(items)] }
70                    }
71                }
72            },
73            FormatDescriptionVersion::V3 => match self.inner {
74                OwnedFormatItemInner::Literal(_) => {
75                    {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("internal error: v3 format descriptions should never have non-UTF8 literals")));
}bug!("v3 format descriptions should never have non-UTF8 literals")
76                }
77                OwnedFormatItemInner::StringLiteral(string) => {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"FormatDescriptionV3Inner",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedLiteral",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([crate::to_tokens::ToTokenTree::into_token_tree(string.as_ref())]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
78                    FormatDescriptionV3Inner::BorrowedLiteral(#(string.as_ref()))
79                },
80                OwnedFormatItemInner::Component(component) => {
81                    // v3 format descriptions have components directly on the item, not as a
82                    // sub-enum. Swap out the name of the enum that is being constructed.
83                    let tokens = component.into_token_stream();
84                    let mut iter = tokens.into_iter().peekable();
85                    if let Some(first) = iter.peek_mut() {
86                        *first = proc_macro::TokenTree::Ident(proc_macro::Ident::new(
87                            "FormatDescriptionV3Inner",
88                            proc_macro::Span::mixed_site(),
89                        ));
90                    } else {
91                        {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("internal error: component should have at least one token")));
}bug!("component should have at least one token")
92                    }
93                    ts.extend(iter);
94                }
95                OwnedFormatItemInner::Compound(items) => {
96                    let items = items
97                        .into_iter()
98                        .map(|item| {
99                            {
    use proc_macro::*;
    let mut ts = TokenStream::new();
    let ts_mut = &mut ts;
    crate::to_tokens::ToTokenStream::append_to(Self {
            version: self.version,
            inner: item,
        }, ts_mut);
    ts_mut.extend([TokenTree::from(Punct::new(',', Spacing::Alone))]);
    ;
    ;
    ts
}quote_! { #S(Self { version: self.version, inner: item }), }
100                        })
101                        .collect::<TokenStream>();
102                    {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"FormatDescriptionV3Inner",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedCompound",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Ident::new(&"const",
                                                Span::mixed_site()))]);
                            ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                                                {
                                                    use proc_macro::*;
                                                    let mut ts = TokenStream::new();
                                                    let ts_mut = &mut ts;
                                                    ts_mut.extend([TokenTree::from(Punct::new('&',
                                                                        Spacing::Alone))]);
                                                    ;
                                                    ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Bracket,
                                                                        {
                                                                            use proc_macro::*;
                                                                            let mut ts = TokenStream::new();
                                                                            let ts_mut = &mut ts;
                                                                            crate::to_tokens::ToTokenStream::append_to(items, ts_mut);
                                                                            ;
                                                                            ts
                                                                        }))]);
                                                    ;
                                                    ts
                                                }))]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
103                        FormatDescriptionV3Inner::BorrowedCompound(const { &[#S(items)] })
104                    }
105                }
106                OwnedFormatItemInner::Optional { format, item } => {
107                    {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"FormatDescriptionV3Inner",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedOptional",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Ident::new(&"format",
                                                Span::mixed_site()))]);
                            ts_mut.extend([TokenTree::from(Punct::new(':',
                                                Spacing::Alone))]);
                            ;
                            crate::to_tokens::ToTokenStream::append_to(format, ts_mut);
                            ts_mut.extend([TokenTree::from(Punct::new(',',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::from(Ident::new(&"item",
                                                Span::mixed_site()))]);
                            ts_mut.extend([TokenTree::from(Punct::new(':',
                                                Spacing::Alone))]);
                            ;
                            ts_mut.extend([TokenTree::from(Punct::new('&',
                                                Spacing::Alone))]);
                            ;
                            crate::to_tokens::ToTokenStream::append_to(Self {
                                    version: self.version,
                                    inner: *item,
                                }, ts_mut);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
108                        FormatDescriptionV3Inner::BorrowedOptional {
109                            format: #S(format),
110                            item: &#S(Self { version: self.version, inner: *item })
111                        }
112                    }
113                }
114                OwnedFormatItemInner::First(items) => {
115                    let items = items
116                        .into_iter()
117                        .map(|item| {
118                            {
    use proc_macro::*;
    let mut ts = TokenStream::new();
    let ts_mut = &mut ts;
    crate::to_tokens::ToTokenStream::append_to(Self {
            version: self.version,
            inner: item,
        }, ts_mut);
    ts_mut.extend([TokenTree::from(Punct::new(',', Spacing::Alone))]);
    ;
    ;
    ts
}quote_! { #S(Self { version: self.version, inner: item }), }
119                        })
120                        .collect::<TokenStream>();
121                    {
    use proc_macro::*;
    ts.extend([TokenTree::from(Ident::new(&"FormatDescriptionV3Inner",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::from(Punct::new(':', Spacing::Joint)),
                TokenTree::from(Punct::new(':', Spacing::Alone))]);
    ;
    ts.extend([TokenTree::from(Ident::new(&"BorrowedFirst",
                        Span::mixed_site()))]);
    ts.extend([TokenTree::Group(Group::new(Delimiter::Parenthesis,
                        {
                            use proc_macro::*;
                            let mut ts = TokenStream::new();
                            let ts_mut = &mut ts;
                            ts_mut.extend([TokenTree::from(Ident::new(&"const",
                                                Span::mixed_site()))]);
                            ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Brace,
                                                {
                                                    use proc_macro::*;
                                                    let mut ts = TokenStream::new();
                                                    let ts_mut = &mut ts;
                                                    ts_mut.extend([TokenTree::from(Punct::new('&',
                                                                        Spacing::Alone))]);
                                                    ;
                                                    ts_mut.extend([TokenTree::Group(Group::new(Delimiter::Bracket,
                                                                        {
                                                                            use proc_macro::*;
                                                                            let mut ts = TokenStream::new();
                                                                            let ts_mut = &mut ts;
                                                                            crate::to_tokens::ToTokenStream::append_to(items, ts_mut);
                                                                            ;
                                                                            ts
                                                                        }))]);
                                                    ;
                                                    ts
                                                }))]);
                            ;
                            ts
                        }))]);
    ;
}quote_append! { ts
122                        FormatDescriptionV3Inner::BorrowedFirst(const { &[#S(items)] })
123                    }
124                }
125            },
126        }
127    }
128}