Как написать собственный производный макрос? - PullRequest
0 голосов
/ 04 ноября 2018

Я пытаюсь написать свой собственный макрос для режима получения в Rust, и в документации на нем несколько примеров.

У меня есть такая структура:

#[derive(MyMacroHere)]
struct Example {
    id: i64,
    value: Option<String>,
}

Я хочу, чтобы мой макрос генерировал метод а-ля

fn set_fields(&mut self, id: i64, value: Option<String>) {
    // ...
}

Каковы основные шаги для использования черты TokenStream для достижения чего-то подобного?

1 Ответ

0 голосов
/ 04 ноября 2018
  1. Создайте ящик для своих процедурных макросов:

    cargo new my_derive --lib
    
  2. Отредактируйте Cargo.toml, чтобы сделать его процедурным макросом:

    [lib]
    proc-macro = true
    
  3. Реализуйте свой процедурный макрос:

    extern crate proc_macro;
    
    use proc_macro::TokenStream;
    
    #[proc_macro_derive(MyMacroHere)]
    pub fn my_macro_here_derive(input: TokenStream) -> TokenStream { 
        // ...
    }
    
  4. Импортировать процедурный макрос и использовать его:

    extern crate my_derive;
    
    use my_derive::MyMacroHere;
    
    #[derive(MyMacroHere)]
    struct Example {
        id: i64,
        value: Option<String>,
    }
    

Сложная часть заключается в реализации макроса. Большинство людей используют ящики syn и quote , чтобы проанализировать входящий код Rust и затем сгенерировать новый код.

Например, документация syn начинается с примера пользовательского производного . Вы будете анализировать структуру (или перечисление или объединение), а затем обрабатывать различные способы определения структуры (единица, кортеж, именованные поля). Вы соберете необходимую информацию (введите, может быть, имя), а затем сгенерируете соответствующий код.

Смотри также:

...