Use the default configuration for rustfmt in all crates, except for the `windows` and `windows-sys` crates.
---------
Co-authored-by: Arlie Davis <ardavis@microsoft.com>
* Fix Debug impls for COM interfaces
Currently, the Debug impl for COM interfaces shows the recursive
interface chain, like so:
```
IDWriteFontFace5(IDWriteFontFace4(IDWriteFontFace3(IDWriteFontFace2(IDWriteFontFace(0xNNN)))))
```
That's not very useful. This PR trims it down to just the current interface:
```
IDWriteFontFace5(0xNNN)
```
* fix build break
---------
Co-authored-by: Arlie Davis <ardavis@microsoft.com>
The definition of a COM interface may inherit from another interface.
These are known as "interface chains". The `#[implement]` macro allows
designers to specify only the minimal set of interface chains that are
needed for a given COM object implementation. The `#[implement]` macro
(and the `#[interface]` macro) work together to pull in the
implementations of all interfaces along the chain.
Unfortunately there is a bug in the implementation of `QueryInterface`
for interface chains. The current `QueryInterface` implementation will
only check the IIDs of the interfaces at the root of the chian, i.e.
the "most-derived" interface. `QueryInterface` will not search the IIDs
of interfaces that are in the inheritance chain.
This bug is demonstrated (detected) by the new unit tests in
`crates/tests/implement_core/src/com_chain.rs`. This PR fixes the bug
by generating an `fn matches()` method that checks the current IID and
then checks the parent interface (if any) by calling its `match()`
method. This fixes the unit test.
Co-authored-by: Arlie Davis <ardavis@microsoft.com>
It is common in COM interfaces for different interfaces to have methods
that have the same name, especially for interface "versions" that
extend the semantics of the underlying interfaces. For example,
look at many of the inheritance relationships in COM interfaces in
DirectWrite (IDWriteTextFormat, IDWriteTextFormat2, IDWriteTextFormat3,
etc.)
This fixes the handling of this situation. All that is necessary is to
use the syntax which explicitly selects a specific trait, when invoking
IFoo_Impl methods. This PR adds unit test coverage for this situation.
Co-authored-by: Arlie Davis <ardavis@microsoft.com>
This provides a new feature for COM developers using the windows-rs crate.
It allows for safe dynamic casting from IUnknown to an implementation object.
It is based on Rust's Any trait.
Any type that is marked with #[implement], except for those that contain
non-static lifetimes, can be used with dynamic casting.
Example:
```rust
struct MyApp { ... }
fn main() {
let my_app = ComObject::new(MyApp { ... });
let iunknown: IUnknown = my_app.to_interface();
do_stuff(&iunknown);
}
fn do_stuff(unknown: &IUnknown) -> Result<()> {
let my_app: ComObject<MyApp> = unknown.cast_object()?;
my_app.internal_method();
Ok(())
}
```
Co-authored-by: Arlie Davis <ardavis@microsoft.com>