1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#![feature(proc_macro_diagnostic)]

use proc_macro::{TokenStream};
use proc_macro2::{TokenTree, Delimiter, Group};
use quote::{quote, quote_spanned};
use syn::parse::{Nothing, Parse, ParseStream, Result};
use syn::token;
use syn::spanned::Spanned;
use syn::{parse_macro_input, Expr, Ident, Token, Type, Visibility};
use syn::buffer::Cursor;

// The below trait was copied from `yew-macro`, originally authored by Justin Starry
// trait Peek<'a, T> {
//     fn peek(cursor: Cursor<'a>) -> Option<(T, Cursor<'a>)>;
// }

/// Parses the following syntax, which aligns with the input of the real
/// `lazy_static` crate.
///
///     lazy_static! {
///         $VISIBILITY static ref $NAME: $TYPE = $EXPR;
///     }
///
/// For example:
///
///     lazy_static! {
///         static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap();
///     }
struct PubCfgUse {
}

impl PubCfgUse {
}

struct PubCfgSemver {

}

impl Parse for PubCfgSemver {
    fn parse(input: ParseStream) -> Result<Self> {
        Ok(PubCfgSemver{})
    }
}

// impl Peek<'_, Self> for PubCfgSemver {
//     fn peek(cursor: Cursor) -> Option<(Self, Cursor)> {
//         None
//     }
// }

// // om_use!(yew @ ^1.21 :: {self as foo, bar});

impl Parse for PubCfgUse {
    fn parse(input: ParseStream) -> Result<Self> {
        let scheme: Ident = input.parse()?;

        let (semver, cursor) = {
            let inner_cursor = input.fork().cursor();
            if let Some((punct, cursor)) = inner_cursor.punct() {
                if punct.as_char() == '@' {
                    (Some(PubCfgSemver::parse(input)), cursor)
                } else {
                    (None, cursor)
                }
            } else {
                (None, inner_cursor)
            }
        };

        //input.parse::<Token![::]>()?;
        // input.parse::<Token![ref]>()?;
        // let name: Ident = input.parse()?;
        // input.parse::<Token![:]>()?;
        // let ty: Type = input.parse()?;
        // input.parse::<Token![=]>()?;
        // let init: Expr = input.parse()?;
        // input.parse::<Token![;]>()?;

        input.parse::<Nothing>()?;

        Ok(PubCfgUse {
        })
    }
}

#[macro_export]
#[proc_macro]
pub fn pubcfg_use(input: TokenStream) -> TokenStream {
    let PubCfgUse {  } = parse_macro_input!(input as PubCfgUse);

    let expanded = quote! {
        // #visibility struct #name;

        // impl std::ops::Deref for #name {
        //     type Target = #ty;

        //     fn deref(&self) -> &#ty {
        //         #assert_sync
        //         #assert_sized

        //         static ONCE: std::sync::Once = std::sync::Once::new();
        //         static mut VALUE: *mut #ty = 0 as *mut #ty;

        //         unsafe {
        //             ONCE.call_once(|| VALUE = #init_ptr);
        //             &*VALUE
        //         }
        //     }
        // }
    };

    TokenStream::from(expanded)
}





///////////


// macro_rules! om_use {
//     ($foo:ident @ ^1.21) => {
//         // The macro will expand into the contents of this block.
//         println!("{}", quote!($foo));
//     };
// }
//
// // om_use!(yew @ ^1.21 :: {self as foo, bar});
// om_use!(bar @ ^1.21 :: {self as baz});
//
// // om_declare!(baz, {
// //     fn foo() -> baz {
// //
// //     }
// // })
//