On Thu, Jun 27, 2019 at 05:06:07PM +0900, Hiroyuki Katsura wrote:
From: Hiroyuki_Katsura <hiroyuki.katsura.0513(a)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