intercom_attributes/
lib.rs

1//! Procedural macro attributes for defining intercom libraries.
2//!
3//! These macros implement various low level items that enable the associated
4//! types to be instantiated and invoked over the COM interface protocol.
5//!
6//! **Instead of depending on this crate directly, the users should depend on
7//! the main `intercom` crate isntead.**
8//!
9//! The split into two crates is an artificial limitation of Rust. The crates
10//! defining procedural macros cannot export anything else than procedural
11//! macros.
12
13#![allow(unused_imports)]
14
15extern crate intercom_common;
16use intercom_common::attributes::*;
17
18extern crate proc_macro;
19use proc_macro::{LexError, TokenStream};
20
21// Note the rustdoc comments on the [proc_macro_attribute] functions document
22// "attributes", not "functions".
23//
24// While at "com_interface" function creates virtual tables, etc. when it is
25// invoked, the attribute doesn't "creates" these. Instead the attribute just
26// "defines" the trait/impl as a COM interface.
27//
28// The runtime documentation for developers is present in the expand_...
29// methods below.
30
31/// Defines an intercom interface.
32///
33/// ```rust,ignore
34/// #[com_interface(IID, base?)]
35/// trait Foo { /* ... */ }
36/// ```
37///
38/// - `IID` - A unique ID of the interface used to query for it. Must be either
39///           a valid GUID or `AUTO_GUID` specifier.
40/// - `base` - Base interface. Defaults to `IUnknown` if not specified.
41///
42/// Associated types: `trait`, `impl Struct`
43///
44/// Intercom interfaces form the basis of the cross language API provided by
45/// the user library. The interfaces define the available methods that can be
46/// called through the interface pointers given to the clients.
47///
48/// Each interface automatically inherits from the base `IUnknown` interface,
49/// which provides the clients a way to perform reference counting and the
50/// ability to query for other interfaces the object might implement.
51#[proc_macro_attribute]
52pub fn com_interface(attr: TokenStream, tokens: TokenStream) -> TokenStream
53{
54    match expand_com_interface(attr, tokens) {
55        Ok(t) => t,
56        Err(e) => panic!("{}", e),
57    }
58}
59
60/// Defines a COM class that implements one or more COM interfaces.
61///
62/// ```rust,ignore
63/// #[com_class(CLSID, interfaces...)]
64/// struct S { /* ... */ }
65/// ```
66///
67/// - `CLSID` - A unique ID of the exposed class. The clients use the class ID
68///             to specify the class when they want to construct an object.
69///             The value must be a valid GUID, `AUTO_GUID` or `NO_GUID`.
70/// - `interfaces` - Any number of interfaces that the class implements.
71///
72/// Associated types: `struct`, `enum`
73///
74/// If the `CLSID` is specified as `NO_GUID`, the class cannot be constructed
75/// by the clients. It can still be returned as a return value from other
76/// intercom methods.
77#[proc_macro_attribute]
78pub fn com_class(attr: TokenStream, tokens: TokenStream) -> TokenStream
79{
80    match expand_com_class(attr, tokens) {
81        Ok(t) => t,
82        Err(e) => panic!("{}", e),
83    }
84}
85
86/// Defines a COM library sub-module.
87///
88/// ```rust,ignore
89/// com_module!(items...)]
90/// ```
91///
92/// - `items` - List of items contained in this module.
93///
94/// The macro results in the implementation of the object creation
95/// infrastructure that allows external clients to load the library and
96/// instantiate the specified types.
97#[proc_macro]
98pub fn com_module(args: TokenStream) -> TokenStream
99{
100    match expand_com_module(args, false) {
101        Ok(t) => t,
102        Err(e) => panic!("{}", e),
103    }
104}
105
106/// Defines the COM library.
107///
108/// ```rust,ignore
109/// com_library!( libid = "...", items...)]
110/// ```
111///
112/// - `libid` - A unique ID that specifies the current intercom library.
113///             Optional, the libid is generated randomly if omitted.
114/// - `items` - List of items contained in this library.
115///
116/// The macro results in the implementation of the object creation
117/// infrastructure that allows external clients to load the library and
118/// instantiate the specified types.
119#[proc_macro]
120pub fn com_library(args: TokenStream) -> TokenStream
121{
122    match expand_com_module(args, true) {
123        Ok(t) => t,
124        Err(e) => panic!("{}", e),
125    }
126}
127
128/// Derives the implementation of the trait ForeignType for a type.
129#[proc_macro_derive(ForeignType)]
130pub fn named_type_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream
131{
132    match expand_bidirectional_type_info(input) {
133        Ok(t) => t,
134        Err(e) => panic!("{}", e),
135    }
136}
137
138/// Derives the implementation of the trait ExternType for a type.
139#[proc_macro_derive(ExternType)]
140pub fn derive_extern_type(input: proc_macro::TokenStream) -> proc_macro::TokenStream
141{
142    match expand_derive_extern_type(input) {
143        Ok(t) => t,
144        Err(e) => panic!("{}", e),
145    }
146}
147
148/// Derives the implementation of the trait ExternInput for a type.
149#[proc_macro_derive(ExternInput)]
150pub fn derive_extern_input(input: proc_macro::TokenStream) -> proc_macro::TokenStream
151{
152    match expand_derive_extern_input(input) {
153        Ok(t) => t,
154        Err(e) => panic!("{}", e),
155    }
156}
157
158/// Derives the implementation of the trait ExternOutput for a type.
159#[proc_macro_derive(ExternOutput)]
160pub fn derive_extern_output(input: proc_macro::TokenStream) -> proc_macro::TokenStream
161{
162    match expand_derive_extern_output(input) {
163        Ok(t) => t,
164        Err(e) => panic!("{}", e),
165    }
166}