2015-11-30 13 views
15

Mam kilka makr w celu zmniejszenia boilerplate przy definiowaniu niektórych krotka-konstrukcjom formularza:Generowanie dokumentacji w makr

macro_rules! new_type (($name:ident, $bytes:expr) => (
    pub struct $name(pub [u8; $bytes]); 
    // some common operations on $name 
)); 

Jednak chciałbym również, aby dokumentować te nowe konstrukcjom. Najlepiej byłoby, gdybym mógł napisać moją dokumentację tuż przed inwokacją makr.

/// A certain type 
new_type!(CertainType, 42); 

Jednak Rust nie będzie generować dokumentację dla CertainType kiedy to nastąpi.

Innym (nie tak elastyczne) Alternatywą byłoby zrobić coś takiego:

macro_rules! new_type (($name:ident, $bytes:expr) => (
    /// Some more generic documentation for $name 
    pub struct $name(pub [u8; $bytes]); 
    // some common operations on $name 
)); 

Jednak, gdy robi, że system makro Rust nie rozszerza tokena $name w komentarzu dokumentacji. Pozostaje nam tylko napisać bardzo ogólną dokumentację w makrze, ale to doprowadziłoby do tego, że moja biblioteka jest dużo gorsza, niż mogłaby być.

Jakie są Twoje zalecenia dotyczące postępowania z tym? Najlepszym rozwiązaniem dla mnie byłaby możliwość napisania konkretnej dokumentacji dla każdego wywołania makra, ale jeśli to nie jest możliwe, byłbym wdzięczny za wskazówki, jak rozszerzyć tokeny w komentarzach do dokumentacji.

+0

wygenerowana dokumentacja nie ma wartości informacyjnej, ponieważ została wygenerowana. utworzyć sekcję w dokumentacji opisującej schemat, ale nie powiększaj dokumentacji. – Arne

Odpowiedz

16

Możliwe jest przechwytywanie komentarzy do dokumentu w wywołaniach makr. Nie jest zbyt szeroko znana, ale dokumentacja Rusta jest faktycznie reprezentowana jako szczególny rodzaj atrybutu dla przedmiotu. Na przykład:

/// Some documentation comment 
pub fn function() {} 

// is equivalent to 

#[doc="Some documentation comment"] 
pub fn function() {} 

I jest możliwe, aby uchwycić atrybuty makr. Istnieje już kilka makr, które korzystają z tej możliwości, najbardziej używany prawdopodobnie będąc bitflags!:

macro_rules! bitflags { 
    ($(#[$attr:meta])* flags $BitFlags:ident: $T:ty { 
     $($(#[$Flag_attr:meta])* const $Flag:ident = $value:expr),+ 
    }) => 
    ... 
} 

Zanotuj $(#[$attr:meta])* część wzoru. Przechwytuje wszystkie atrybuty umieszczone przed danym elementem we wzorze. Jeśli napiszesz tam komentarz do dokumentu, zostanie on faktycznie przekonwertowany na atrybut doc i zostanie przekazany do rustdoc, jak zwykle. Poniżej znajduje się przykład z quick_error skrzyni, która używa również to podejście:

quick_error! { 
    #[derive(Debug)] 
    pub enum SomeError { 
     /// IO Error 
     Io(err: io::Error) {} 
     /// Arbitrary system error 
     Sys(errno: nix::Errno) {} 
    } 
} 

i działa - here jest przykładem konstrukcji wytwarzanych przez quick_error makro i here to jej definicja.

+0

Dzięki. To rozwiązuje mój problem. Wiedziałem, że komentarze do dokumentu zostały przetłumaczone na atrybuty, ale nie zdawałem sobie sprawy, że mogę dopasować je do nich w definicji makra. – dnaq