-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for Event notifications #60
Conversation
Hi! Thanks for looking into this 😄 I'll have more time next week to review this properly but overall this sounds great 🚀 About the waiting doc tests: I think the best thing would be to start a new thread which starts a short lived process (like ping -n 1 127.0.0.1) in a loop, just to make sure tests always finish in a timely manner. |
I've fixed tests. Also, as much as I wanted to put the two new functions (at the bottom of the |
I've again tried to implement Then again, I'm pretty much experimenting and seeing what sticks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did an initial review for most of the code except the desr stuff.
Awesome work 🚀! Thanks again for implementing this
@@ -56,13 +57,13 @@ impl WMIConnection { | |||
/// # use wmi::*; | |||
/// # use std::collections::HashMap; | |||
/// # use futures::executor::block_on; | |||
/// # fn main() -> Result<(), wmi::WMIError> { | |||
/// # fn main() -> wmi::WMIResult<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have the time, splitting this PR into 2 (one with this kind of changes, the other with your new logic) would be great
src/result_enumerator.rs
Outdated
where | ||
S: serde::Serializer | ||
{ | ||
let data = self.serialization_data().map_err(Error::custom)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you actually want here, which I think avoids all the lifetime problems, is to generate a "map" and not a "struct"
The distinction Serde makes [between structs and maps] is that structs have keys that are compile-time constant strings and will be known at deserialization time without looking at the serialized data.
https://serde.rs/impl-serialize.html#serializing-a-struct
impl Serialize for IWbemClassWrapper {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer
{
let props = self.list_properties().map_err(Error::custom)?;
let mut map = serializer.serialize_map(Some(props.len()))?;
for property in props.iter() {
let value = self.get_property(&property).unwrap();
map.serialize_entry(property, &value)?;
}
map.end()
}
}
Could you also add to the src\query.rs::it_works
test to check that it serializes correctly?
(But you should keep the Deserializer
vs Deserializer<'a>
change: the new version is needed for the new code to work, and is better anyway)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm kinda mad this works without any problems. But it is a better way of handling this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀🚀
just a small nit-pick about naming conventions, and we're ready to merge this
Also: merge from main, I fixed the CI workflow so the tests should run now
src/query.rs
Outdated
|
||
pub enum FilterValue { | ||
Bool(bool), | ||
Number(i64), | ||
Str(&'static str), | ||
String(String), | ||
Is_A(&'static str), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be IsA
, and the function is_a()
(just the expected Rust conventions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have done that from the beginning, but for some reason, I focused on IsA
.
Anyway, I've changed this now.
src/query.rs
Outdated
@@ -51,7 +53,17 @@ impl From<bool> for FilterValue { | |||
} | |||
} | |||
|
|||
/// Build an SQL query for the given filters, over the given type (using it's name and fields). | |||
impl FilterValue { | |||
pub fn IsA<'de, T>() -> WMIResult<Self> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe copy-paste a part of the example in lib.rs
as a docstring for this? (No need to actually query anything, just a simplified example)
|
||
#[derive(Debug, Error)] | ||
#[non_exhaustive] | ||
pub enum WMIError { | ||
/// You can find a useful resource for decoding error codes [here](https://docs.microsoft.com/en-us/windows/win32/wmisdk/wmi-error-constants) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
Glad to hear it! 😄 Also, you need to approve the workflow run |
Ah sorry you were bitten by the chrono/time features. Maybe add |
Ok, fixed |
I forgot about usings, my bad |
Released as version 0.11.3, thanks a lot @MineBartekSA 🎉 |
In this pull request, I'm adding support for WMI Event notifications and deserialization of the Unknown Variant.
This PR closes #46.
Significant changes were made to
notifiaction.rs
,variant.rs
,result_enumerator.rs
,query.rs
,variant_de.rs
, andwbem_class_de.rs
.Other files only received some minor changes.
Major changes
I've added a new file called
notifiaction.rs
, which contains newWMIConnection
methods used to subscribe to WMI Event notifications. They utilize theExecNoticicationQuery
(and for async the Async equivalent) method.Since intrinsic events hold event data inside their properties, I've added appropriate
Variant
variants and their processing.The new
Variant::Unknown(IUnknownWrapper)
is a temporary variant used to pass theIUknown
to the CIM conversion stage. From there it is converted into theVariant::Object(IWbemClassWrapper)
using theIUknown::QueryInterface()
method.Also, because of how intrinsic events are queried, I've added new
FilterValue
variants.New variants add support for the
WITHIN
clause and theISA
operator.I've attempted to add deserialization of the
Variant::Object
and somewhat succeeded.But it resulted in a quite major change to the
wbem_class_de::Deserializer
.Since I don't know how to handle lifetimes and borrows that well, I needed to remove its lifetimes and make it own the
IWbemClassWrapper
copy.I don't think this should break or change anything major, besides the need to clone the
IWbemClassWrapper
, which now implements theClone
trait.I also wanted to add serialization to
IWbemClassWrapper
, sinceVariant
implementsSerialize
,but for the same reason as above, I failedand I've somewhat succeeded.Minor changes
Most minor changes are attributed to documentation or Clippy suggestions.
I've also unified returns to all use the
WMIResult
alias instead ofResult<_, WMIError>
.Lastly, I also fixed the
wbem_class_de::tests::it_desr_into_map
test. It was failing for me since I don't have theen-US
lang.Comments, suggestions, and explanations would be very welcome.
Also, please note that doc tests might not ever complete, or they will only complete after a while because they will wait for a new process to start.