2017-02-02 18 views
2

構造体宣言のフィールド名と型を使用できるようにするためにRustマクロを記述しようとしていますが、まだ構造体を生成する必要があります。マクロで構造体フィールドの可視性を保持する

構造体の可視性(可視性:The Little Book of Rust Macros)のオプション属性で作業していますが、個々のフィールドにpubというオプションの存在を処理する方法を理解することはできません。

は、これまで私が持っている:

macro_rules! with_generic { 
    ($(#[$struct_meta:meta])* 
    pub struct $name:ident { $($fname:ident : $ftype:ty), *} 
    ) => { 
     with_generic![(pub) $(#[$struct_meta])* struct $name {$($fname: $ftype) ,*}]; 
    }; 

    ($(#[$struct_meta:meta])* 
    struct $name:ident { $($fname:ident : $ftype:ty), *} 
    ) => { 
     with_generic![() $(#[$struct_meta])* struct $name {$($fname: $ftype), *}]; 
    }; 

    (
    ($($vis:tt)*) 
    $(#[$struct_meta:meta])* 
    struct $name:ident { $($fname:ident : $ftype:ty), *} 
    ) => { 
     // emit the struct here 
     $(#[$struct_meta])* 
     $($vis)* struct $name { 
      $($fname: $ftype,)* 
     } 

     // I work with fname and ftypes here 
    } 
} 

そして、それは

with_generic! { 
    #[derive(PartialEq, Eq, Debug)] 
    pub struct Person { 
     first_name: String, 
     last_name: String 
    } 
} 

または

with_generic! { 
    #[derive(PartialEq, Eq, Debug)] 
    struct PrivatePerson { 
     first_name: String, 
     last_name: String 
    } 
} 

ようなもので動作しますが、動作しません

with_generic! { 
    #[derive(PartialEq, Eq, Debug)] 
    struct MixedPerson { 
     pub first_name: String, 
     last_name: String 
    } 
} 

私はその最後のケースでマクロを動作させる方法についていくつかの助けをしたいと思います。バインディングの可視性に使用されるタイプなど、ここで基本的なものが不足しているような気がします。フィールド名と型を取得している間に構造体ツリー全体をバインドする方法があれば、それも問題ありません。

また、ライフタイムパラメータを持つ構造体を使用する方法を知りたいのですが、別の質問にする必要があります。

答えて

2

できません。少なくとも、単一の非再帰的ルールではありません。これは、Rustには可視性のためのマクロマッチャーがないためです。

parse-macros crateには、parse_struct!マクロが含まれています。このマクロは、定義を完全に解析するために必要な作業を示しています。短いバージョン: "pubを持っている"と "pubを持っていない"のそれぞれに1つのルールで、各フィールドを個別に解析する必要があります。

また、もう1つのマクロにはまだ説明されていないことに注意してください。フィールド上の属性は、それらが機能するためのドキュメントコメントに必要です。

まもなく、マクロ1.1は安定しているはずです(マクロを派生として表現でき、古いバージョンのRustは気にしないと仮定して)。

+0

"マクロではまだ説明していない別のケースがあることにも気づくでしょう。フィールドの属性は、ドキュメントのコメントに必要です。"うわー、何か忘れてしまったことを知っています。あなたのコードを見て(btw ...すばらしいもの)、私は今どこで句のような他のものをたくさん忘れていることに気付きました。あなたは正しいですが、私は本質的にカスタムが欲しいと思っています:マクロ1.1がそこでどのように役立つかについてもっと詳しく読むことができますか? – lloydmeta

+0

@lloydmetaこの時点では、私が知っているわけではありません。私はソースで「serde-derive」のようなものを突き止めるだけです。 –

+1

https://doc.rust-lang.org/beta/book/procedural-macroshtml – Shepmaster

1

錆1.15は、この質問をした直後にofficially releasedとなり、@DKのようにprocedural macros(カスタム派生)のサポートをもたらします。言った。

今後は、カスタムが構造体を手動で再発行する必要がなくなったため、この問題を完全に解決するための標準的な方法がカスタムと考えられます。

関連する問題