On Thu, Jun 27, 2019 at 05:06:07PM +0900, Hiroyuki Katsura wrote: > From: Hiroyuki_Katsura <hiroyuki.katsura.0...@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 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs