[Libguestfs] [PATCH 6/9] Rust bindings: Add generator of function signatures
Richard W.M. Jones
rjones at redhat.com
Thu Jun 27 08:58:28 UTC 2019
On Thu, Jun 27, 2019 at 05:06:07PM +0900, Hiroyuki Katsura wrote:
> From: Hiroyuki_Katsura <hiroyuki.katsura.0513 at gmail.com>
>
> ---
> generator/rust.ml | 137 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 137 insertions(+)
>
> diff --git a/generator/rust.ml b/generator/rust.ml
> index a229d5eac..aa8b249ff 100644
> --- a/generator/rust.ml
> +++ b/generator/rust.ml
> @@ -59,8 +59,10 @@ let generate_rust () =
> generate_header CStyle LGPLv2plus;
>
> pr "
> +use std::collections;
> use std::ffi;
> use std::slice;
> +use std::ptr;
> use std::os::raw::c_char;
>
>
> @@ -130,6 +132,18 @@ impl CreateFlags {
> }
> }
>
> +fn arg_string_list (v: &Vec<String>) -> Vec<*const i8> {
> + let length = v.len();
> + let mut w = Vec::new();
> + for x in v.iter() {
> + let y: &str = x;
> + let s = ffi::CString::new(y).unwrap();
> + w.push(s.as_ptr());
> + }
> + w.push(ptr::null());
> + w
> +}
> +
> impl Handle {
> pub fn create() -> Result<Handle, &'static str> {
> let g = unsafe { guestfs_create() };
> @@ -151,6 +165,10 @@ impl Handle {
> }
> }\
>
> +pub struct Error {
> + // TODO
> +}
> +
> pub struct UUID {
> uuid: [u8; 32]
> }
> @@ -226,6 +244,8 @@ impl UUID {
> pr " }\n";
> pr "}\n"
> ) external_structs;
> +
> + (* generate structs for optional arguments *)
> List.iter (
> fun ({ name = name; shortdesc = shortdesc;
> style = (ret, args, optargs) }) ->
> @@ -275,3 +295,120 @@ impl UUID {
> pr "}\n\n";
> );
> ) (actions |> external_functions |> sort);
> +
> + pr "impl Handle {\n";
> + List.iter (
> + fun ({ name = name; shortdesc = shortdesc;
> + style = (ret, args, optargs) } as f) ->
> + let cname = snake2caml name in
> + pr " /// %s \n" shortdesc;
> + pr " pub fn %s" name;
> +
> + (* generate arguments *)
> + pr "(&self, ";
> + let comma = ref false in
> + List.iter (
> + fun arg ->
> + if !comma then pr ", ";
> + comma := true;
> + match arg with
> + | Bool n -> pr "%s: bool" n
> + | Int n -> pr "%s: i32" n
> + | Int64 n -> pr "%s: i64" n
> + | String (_, n) -> pr "%s: String" n
> + | OptString n -> pr "%s: Option<String>" n
> + | StringList (_, n) -> pr "%s: Vec<String>" n
> + | BufferIn n -> pr "%s: Vec<u8>" n
> + | Pointer (_, n) -> pr "%s: usize" n
> + ) args;
> + if optargs <> [] then (
> + if !comma then pr ", ";
> + comma := true;
> + pr "optargs: OptArgs%s" cname
> + );
> + pr ")";
> +
> + (* generate return type *)
> + pr " -> Result<";
> + (match ret with
> + | RErr -> pr "()"
> + | RInt _ -> pr "i32"
> + | RInt64 _ -> pr "i64"
> + | RBool _ -> pr "bool"
> + | RConstString _
> + | RString _ -> pr "String"
> + | RConstOptString _ -> pr "Option<String>"
> + | RStringList _ -> pr "Vec<String>"
> + | RStruct (_, sn) ->
> + let sn = camel_name_of_struct sn in
> + pr "%s" sn
> + | RStructList (_, sn) ->
> + let sn = camel_name_of_struct sn in
> + pr "Vec<%s>" sn
> + | RHashtable _ -> pr "collections::HashMap<String, String>"
> + | RBufferOut _ -> pr "Vec<u8>");
> + pr ", Error> {\n";
> +
> + let _pr = pr in
> + let pr fs = indent 2; pr fs in
> + List.iter (
> + function
> + | Bool n ->
> + pr "let c_%s = if %s { 1 } else { 0 };\n" n n
> + | String (_, n) ->
> + (* TODO: handle errors *)
> + pr "let c_%s = \n" n;
> + pr " ffi::CString::new(%s).expect(\"CString::new failed\").as_ptr();\n" n;
> + | OptString n ->
> + pr "let c_%s = match %s {" n n;
> + pr " Some(s) => \n";
> + pr " ffi::CString::new(s)\n";
> + pr " .expect(\"CString::new failed\")\n";
> + pr " .as_ptr(),\n";
> + pr " None => ptr::null(),\n";
> + pr "};\n";
> + | StringList (_, n) ->
> + pr "let c_%s_v = arg_string_list(%s);\n" n n;
> + | BufferIn n ->
> + pr "let c_%s = ffi::CString::new(%s)\n" n n;
> + pr " .expect(\"CString::new failed\")\n";
> + pr " .as_ptr();\n";
> + pr "let c_%s_len = %s.len();\n" n n;
> + | Int _ | Int64 _ | Pointer _ -> ()
> + ) args;
> +
> + (* TODO: handle optargs *)
> + if optargs <> [] then (
> + );
> +
> + (match ret with
> + | RBufferOut _ ->
> + pr "let mut size = 0;\n"
> + | _ -> ()
> + );
> +
> + pr "\n";
> +
> + pr "let r = unsafe { %s(self.g" f.c_function;
> + List.iter (
> + fun arg ->
> + pr ", ";
> + match arg with
> + | Bool n | String (_, n) | OptString n -> pr "c_%s" n
> + | Int n | Int64 n -> pr "%s" n
> + | Pointer _ -> pr "ptr::null()" (* XXX: what is pointer? *)
It's used only by one libguestfs function (guestfs_add_domain), and it
requires you to look at the rust libvirt bindings to find out how to
implement it. It's safe to ignore it for now.
> + | StringList (_, n) -> pr "&c_%s as *const *const c_char" n
> + | BufferIn n -> pr "c_%s, c_%s_len" n n
> + ) args;
> + (match ret with
> + | RBufferOut _ -> pr ", &size as *const usize"
> + | _ -> ()
> + );
> + pr ") };\n";
> +
> + pr "unimplemented!()\n";
> + let pr = _pr in
> +
> + pr " }\n\n"
> + ) (actions |> external_functions |> sort);
> + pr "}\n"
> --
> 2.20.1 (Apple Git-117)
This patch looks OK.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
More information about the Libguestfs
mailing list