use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use syn::{parse::{Parse, ParseStream}, Ident, Result, LitStr, token::As};
use quote::quote;
use std::str::FromStr;
struct Bsget {
url: LitStr,
ident: Option<Ident>,
}
impl Parse for Bsget {
fn parse(input: ParseStream) -> Result<Self> {
let url = input.parse()?;
let ident = match input.parse::<As>() {
Ok(_) => Some(input.parse()?),
Err(_) => None,
};
Ok(Self {
url,
ident,
})
}
}
fn fetch(url: &str) -> String {
ureq::get(url)
.call()
.and_then(|mut r| r.body_mut().read_to_string())
.expect("failed to perform HTTP get")
}
#[proc_macro]
pub fn bsget(item: TokenStream) -> TokenStream {
let bsget = syn::parse_macro_input!(item as Bsget);
let url = bsget.url.value();
let data = fetch(&url);
let code = TokenStream2::from_str(&data).expect("failed to parse code");
match bsget.ident {
Some(ident) => {
quote! {
mod #ident {
#code
}
}
},
None => {
quote! {
#code
}
}
}.into()
}