dundarious
9 months ago
Pardon me, but I prefer the original by 1 million miles.
let res = raw_api::query("SELECT * FROM Win32_Fan");
for obj in res {
if obj.get_attr("ActiveCooling") == Value::Bool(true) {
if let Value::String(name) = obj.get_attr("Name") {
if let Value::UI8(speed) = obj.get_attr("DesiredSpeed") {
println!("Fan `{name}` is running at {speed} RPM");
}
}
}
}
If actually concerned about the need to know UI8, then create a typedef DesiredSpeedT or similar. This is equivalent to the struct Fan.Edit: I understand the post is probably more of a playful exercise than anything else, but I really think the original is far far better (smaller, simpler, etc.) and hope that is not lost on people.
ohr
9 months ago
That's understandable, but I think it depends on how many different structs like this you have and how many fields you need to work with (for our usecase, we had tens of structs with tens of fields each).
There's also an Alternatives section in the article about other approaches that can achieve similar results, but of course 'do nothing' is also a valid option.
Edit: > If actually concerned about the need to know UI8 ..
Just a small note: even if you don't care about the fact that it's a UI8, you still have to use the correct type. For example, if the field happens to be returned as UI4, this code won't work!
dundarious
9 months ago
Right, but isn't the struct definition equivalent in line count and effort compared to some typedefs and perhaps a handful of trivial-to-inspect oneline helper functions?
Regarding the UI8, don't you have to get your version's struct data member type correct to the exact same degree as a typedef in my suggestion?
ohr
9 months ago
> don't you have to get your version's struct data member type correct
No, since Serde will happyly fill a `u64` field with any other `u{8,16,32}` value, and even with signed types (as long as the actual value is non-negative) - this is sort of what happens when you deserialize a JSON `[1, 2, 3]` into `[u64]`.
dundarious
9 months ago
Yes, but an equivalent to `impl<'de> Deserializer<'de> for ValueDeserializer` handles that. That could be a useful helper.
LtWorf
9 months ago
I wrote typedload in python. Once they show you an API with hundreds of types you appreciate not having to do like that all the time.
dundarious
9 months ago
I don't see the issue with just using an equivalent to `impl<'de> Deserializer<'de> for ValueDeserializer` then.
LtWorf
9 months ago
There's unions, there's stuff that uses reserved words in the language as field names... You are obviously not familiar with this task.
dundarious
9 months ago
The "generic macro over struct definitions" approach is the one that has at least some trouble dealing with these situations, not the "getter function with string argument" approach. I've had to do plenty of json and protocol buffers wrangling (meaningfully different, I know), and versioned packed struct memcpy/reinterpret_cast "parsing" as well.
My point is I don't want to do "this task" at all if "this task" means layering funky auto-generated machinery on top of what is already a perfectly reasonable API.
olalonde
9 months ago
Why? It's much more verbose and error prone (e.g. "stringly typed"). Do you never deserialize JSON?
dundarious
9 months ago
What's the difference between mistyping in the string here and mistyping in the struct definition? And yes I have.
olalonde
9 months ago
You only need to get it right once, and from then on the compiler will catch any mistakes if you use it incorrectly. In contrast, every time you write obj.get_attr("DesiredSpeed"), there's a chance you'll make a typo and the compiler won't warn you about it.