From 89b56ddccf6ebb77a4be15966c5f3042c1184b80 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Thu, 10 Oct 2019 11:39:21 +0000 Subject: [PATCH] util: C-wrapped data don't need to be cloneable --- src/keyboard.rs | 5 +++-- src/layout.rs | 4 +++- src/util.rs | 33 +++++++++++++++++++++++---------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/keyboard.rs b/src/keyboard.rs index 10d22747..cce713a5 100644 --- a/src/keyboard.rs +++ b/src/keyboard.rs @@ -10,6 +10,7 @@ use ::action::Action; use std::io::Write; use std::iter::{ FromIterator, IntoIterator }; +use ::util::CloneOwned; /// Gathers stuff defined in C or called by C pub mod c { @@ -48,13 +49,13 @@ pub mod c { pub extern "C" fn squeek_key_is_pressed(key: CKeyState) -> u32 { //let key = unsafe { Rc::from_raw(key.0) }; - return key.to_owned().pressed as u32; + return key.clone_owned().pressed as u32; } #[no_mangle] pub extern "C" fn squeek_key_is_locked(key: CKeyState) -> u32 { - return key.to_owned().locked as u32; + return key.clone_owned().locked as u32; } #[no_mangle] diff --git a/src/layout.rs b/src/layout.rs index a37b8875..574b17c1 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -27,6 +27,8 @@ use ::action::Action; use ::float_ord::FloatOrd; use ::keyboard::*; +use ::util::CloneOwned; + /// Gathers stuff defined in C or called by C pub mod c { use super::*; @@ -270,7 +272,7 @@ pub mod c { ) { let layout = unsafe { &mut *layout }; - let view_name = match key.to_owned().action { + let view_name = match key.clone_owned().action { Action::SetLevel(name) => { Some(name.clone()) }, diff --git a/src/util.rs b/src/util.rs index 59b9f51b..935250b9 100644 --- a/src/util.rs +++ b/src/util.rs @@ -4,6 +4,8 @@ use std::collections::HashMap; use std::iter::FromIterator; pub mod c { + use super::*; + use std::cell::RefCell; use std::ffi::{ CStr, CString }; use std::os::raw::c_char; @@ -63,7 +65,7 @@ pub mod c { /// RefCell will enforce them dynamically (only 1 writer/many readers) /// Rc is implied and will ensure timely dropping #[repr(transparent)] - pub struct Wrapped(*const RefCell); + pub struct Wrapped(*const RefCell); // It would be nice to implement `Borrow` // directly on the raw pointer to avoid one conversion call, @@ -73,7 +75,7 @@ pub mod c { // Unfortunately, that needs a `Ref` struct with self-referential fields, // which is a bit too complex for now. - impl Wrapped { + impl Wrapped { pub fn wrap(state: Rc>) -> Wrapped { Wrapped(Rc::into_raw(state)) } @@ -91,20 +93,31 @@ pub mod c { Rc::into_raw(used_rc); // prevent dropping the original reference rc } + } + + impl Clone for Wrapped { + fn clone(&self) -> Wrapped { + Wrapped::wrap(self.clone_ref()) + } + } + + /// ToOwned won't work here + /// because it's really difficult to implement Borrow on Wrapped + /// with the Rc> chain on the way to the data + impl CloneOwned for Wrapped { + type Owned = T; - /// Create a copy of the underlying data - pub fn to_owned(&self) -> T { + fn clone_owned(&self) -> T { let rc = self.clone_ref(); let r = rc.borrow(); r.to_owned() } } - - impl Clone for Wrapped { - fn clone(&self) -> Wrapped { - Wrapped::wrap(self.clone_ref()) - } - } +} + +pub trait CloneOwned { + type Owned; + fn clone_owned(&self) -> Self::Owned; } pub fn hash_map_map(map: HashMap, mut f: F)