diff --git a/generator/rust.ml b/generator/rust.ml index a1735602c..1f5cefa62 100644 --- a/generator/rust.ml +++ b/generator/rust.ml @@ -72,6 +72,42 @@ extern \"C\" { } "; + (* event enum *) + pr "\n"; + pr "pub enum Event {\n"; + List.iter ( + fun (name, _) -> + pr " %s,\n" (snake2caml name) + ) events; + pr "}\n\n"; + + pr "impl Event {\n"; + pr " pub fn to_u64(&self) -> u64 {\n"; + pr " match self {\n"; + List.iter ( + fun (name, i) -> + pr " Event::%s => %d,\n" (snake2caml name) i + ) events; + pr " }\n"; + pr " }\n"; + pr " pub fn from_bitmask(bitmask: u64) -> Option {\n"; + pr " match bitmask {\n"; + List.iter ( + fun (name, i) -> + pr " %d => Some(Event::%s),\n" i (snake2caml name) + ) events; + pr " _ => None,\n"; + pr " }\n"; + pr " }\n"; + pr "}\n\n"; + + pr "pub const EVENT_ALL: [Event; %d] = [\n" (List.length events); + List.iter ( + fun (name, _) -> + pr " Event::%s,\n" (snake2caml name) + ) events; + pr "];\n"; + List.iter ( fun { s_camel_name = name; s_name = c_name; s_cols = cols } -> pr "\n"; @@ -356,7 +392,7 @@ extern \"C\" { pr "}\n"; - pr "impl Handle {\n"; + pr "impl<'a> Handle<'a> {\n"; List.iter ( fun ({ name = name; shortdesc = shortdesc; longdesc = longdesc; style = (ret, args, optargs) } as f) -> diff --git a/rust/src/base.rs b/rust/src/base.rs index 02ad33535..c17607cb3 100644 --- a/rust/src/base.rs +++ b/rust/src/base.rs @@ -17,6 +17,9 @@ */ use crate::error; +use crate::event; +use crate::guestfs; +use std::collections; #[allow(non_camel_case_types)] #[repr(C)] @@ -34,31 +37,37 @@ extern "C" { const GUESTFS_CREATE_NO_ENVIRONMENT: i64 = 1; const GUESTFS_CREATE_NO_CLOSE_ON_EXIT: i64 = 2; -pub struct Handle { +pub struct Handle<'a> { pub(crate) g: *mut guestfs_h, + pub(crate) callbacks: collections::HashMap< + event::EventHandle, + Box>, + >, } -impl Handle { - pub fn create() -> Result { +impl<'a> Handle<'a> { + pub fn create() -> Result, error::Error> { let g = unsafe { guestfs_create() }; if g.is_null() { Err(error::Error::Create) } else { - Ok(Handle { g }) + let callbacks = collections::HashMap::new(); + Ok(Handle { g, callbacks }) } } - pub fn create_flags(flags: CreateFlags) -> Result { + pub fn create_flags(flags: CreateFlags) -> Result, error::Error> { let g = unsafe { guestfs_create_flags(flags.to_libc_int()) }; if g.is_null() { Err(error::Error::Create) } else { - Ok(Handle { g }) + let callbacks = collections::HashMap::new(); + Ok(Handle { g, callbacks }) } } } -impl Drop for Handle { +impl<'a> Drop for Handle<'a> { fn drop(&mut self) { unsafe { guestfs_close(self.g) } } diff --git a/rust/src/error.rs b/rust/src/error.rs index 705ee1735..e526121e8 100644 --- a/rust/src/error.rs +++ b/rust/src/error.rs @@ -56,7 +56,7 @@ impl convert::From for Error { } } -impl base::Handle { +impl<'a> base::Handle<'a> { pub(crate) fn get_error_from_handle(&self, operation: &'static str) -> Error { let c_msg = unsafe { guestfs_last_error(self.g) }; let message = unsafe { utils::char_ptr_to_string(c_msg).unwrap() }; diff --git a/rust/src/event.rs b/rust/src/event.rs new file mode 100644 index 000000000..c363e913a --- /dev/null +++ b/rust/src/event.rs @@ -0,0 +1,4 @@ +#[derive(Hash, PartialEq, Eq)] +pub struct EventHandle { + eh: i32, +} diff --git a/rust/src/lib.rs b/rust/src/lib.rs index cc41a99f8..81adef2a3 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -18,9 +18,11 @@ mod base; mod error; +mod event; mod guestfs; mod utils; pub use crate::base::*; pub use crate::error::*; +pub use crate::event::*; pub use crate::guestfs::*; diff --git a/rust/tests/040_create_multiple.rs b/rust/tests/040_create_multiple.rs index cc93554a3..970c988af 100644 --- a/rust/tests/040_create_multiple.rs +++ b/rust/tests/040_create_multiple.rs @@ -18,7 +18,7 @@ extern crate guestfs; -fn create() -> guestfs::Handle { +fn create<'a>() -> guestfs::Handle<'a> { match guestfs::Handle::create() { Ok(g) => g, Err(e) => panic!("fail: {:?}", e),