-
Notifications
You must be signed in to change notification settings - Fork 7
Rust bindings for qclib #5
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
base: main
Are you sure you want to change the base?
Conversation
0c75339
to
180d921
Compare
Ok(LayerCategory::from_raw(category)) | ||
} | ||
|
||
impl_attr!(layer_name() -> String = LayerName); |
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.
@Stefan-Raspl: according to the qclib docs, qc_layer_name
is only not available for KVM hypervisors. Is this an oversight in the documentation? If it is available for all layers, I make this a common attribute like the ones above.
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.
Could you point at the exact piece of documentation with that statement?
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.
It's missing in the available attributes for KVM hypervisors.
Rust bindings implement an FFI interface to the qclib C library and allows the usage of qclib in Rust context. The bindings come in two crates: * qclib-sys: contains the raw FFI interface to the C library. * qclib: contains a safe and idiomatic abstraction for data types and functions provided by the C library. Signed-off-by: Bjoern Walk <[email protected]>
Add native Rust implementations of zhypinfo and zname as an example for the usage of the bindings. Signed-off-by: Bjoern Walk <[email protected]>
180d921
to
3c41a17
Compare
if rc < 0 { | ||
return Err(Error { code: rc }); | ||
} |
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'll add handling rc > 0
as well (occurs when no consistent data is available after migration).
|
||
[package] | ||
name = "qclib" | ||
version = "2.0.0" |
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's the significance of "version"? Should this reflect the actual package's version?
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.
This is the version of the rust crate (library). I had it aligned with the version of the C library, but this will get awkward if we have changes in the crate and release a new version while the C library has not changed. I commented here before changing it. I'm open to suggestions since I'm not sure what the best handling is.
@@ -0,0 +1,22 @@ | |||
[workspace.package] | |||
edition = "2021" |
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.
Is this the year of the code?
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.
No, it's the Rust edition (think C standard revisions like C89, C11 and so on) used for this crate.
@@ -0,0 +1 @@ | |||
../../LICENSE |
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.
Use a symlink instead? I assume Rust strictly requires a license file..?
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.
It is one :)
Yes, to publish the crate Rust requires an explicit license.
qc: self.qc, | ||
layer: self.layer, | ||
}), | ||
LayerType::LparGroup => todo!(), |
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.
So this would be essentially a preview or beta version..?
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 prefer, sure. I just implemented what I needed. The other layers should be trivial to implement but I don't have a testing environment available, so I left them out.
I can implement the rest or we could change the version to -beta
, let me know what you prefer.
#![allow(nonstandard_style)] | ||
|
||
pub type qc_layer_type = ::std::os::raw::c_uint; | ||
pub const QC_LAYER_TYPE_CEC: qc_layer_type = 1; |
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 don't feel too well with these re-defines. Are these really necessary? I would have assumed all it takes is a couple 'extern "C"' wrapped functions, no?!
At the very least, we should look into automating the generation of these as part of the build procedure.
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 are you worried about?
Yes, this file can be created automatically via bindgen (which in fact I didtried, but the results were suboptimal). I didn't want to mess with the build scripts for qclib, but I can look into it if you prefer.
I need the type definitions and their corresponding values in Rust context, I don't see a way around them.
map: &mut serde_json::Map<String, serde_json::Value>, | ||
) -> Result<()> { | ||
json_pair!(map <- Manufacturer: string? = self.manufacturer()?); | ||
json_pair!(map <- Type: string? = self.machine_type()?); |
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.
Might be my lack of knowledge of Rust: This is for generating json output? We already have routines in qclib - why re-implement?!
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.
Yes, it's for JSON output. The qc_export_json
function that qclib provides dumps the JSON content to stdout
and doesn't give the user any control over that.
I want to give the user more control, so I just create a JSON object and return that, allowing the user to process that how they prefer. It's done via a defacto standard dependencies for JSON handling and deserialization.
let mut rc = 0; | ||
let layers = unsafe { sys::qc_get_num_layers(self.as_raw(), &mut rc) }; | ||
|
||
if rc < 0 { |
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 I got this right, we're calling the C version of get_num_layers() here, but still check return codes. Why would we want to do that - to better the C version of the code...?
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 don't understand, why wouldn't we check the return code? We are calling into the raw C function, so we need to check rc
.
This pull request adds bindings for the Rust programming language.
The second patch with examples is optional but provides usage example for the bindings by reimplementing
zhypinfo
andzname
in Rust.