diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2021-06-26 17:08:15 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2021-06-26 17:08:15 -0300 |
commit | 7a9a4290248ee9019303e9d866f75e4104fe51da (patch) | |
tree | ef6bbaa4acab85e7be58b02937ff209fe4613dd3 | |
parent | 42e6fa41a8f3903e2b8b05baf212b6d2c405d950 (diff) |
Clean up Word/Eol
-rw-r--r-- | src/lib.rs | 115 | ||||
-rw-r--r-- | src/word.rs | 130 |
2 files changed, 138 insertions, 107 deletions
diff --git a/src/lib.rs b/src/lib.rs index b64cac4..c8b0d80 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -162,9 +162,11 @@ mod eat; mod infoid; mod internals; mod pluginfo; +mod word; pub use eat::*; pub use infoid::InfoId; +pub use word::*; use pluginfo::PluginInfo; @@ -173,7 +175,6 @@ use std::ffi::{CString, CStr}; use std::marker::PhantomData; use std::mem; use std::mem::ManuallyDrop; -use std::ops; use std::panic::catch_unwind; use std::ptr; use std::rc::Rc; @@ -235,60 +236,6 @@ pub struct PluginHandle { info: PluginInfo, } -/// Arguments passed to a hook, until the next argument. -/// -/// # Examples -/// -/// ``` -/// use hexchat_plugin::{PluginHandle, Word, WordEol, Eat}; -/// -/// fn cmd_foo(ph: &mut PluginHandle, arg: Word, arg_eol: WordEol) -> Eat { -/// if arg.len() < 3 { -/// ph.print("Not enough arguments"); -/// } else { -/// ph.print(&format!("{} {} {}", arg[0], arg[1], arg[2])); -/// } -/// hexchat_plugin::EAT_ALL -/// } -/// -/// fn on_privmsg(ph: &mut PluginHandle, word: Word, word_eol: WordEol) -> Eat { -/// if word.len() > 0 && word[0].starts_with('@') { -/// ph.print("We have message tags!?"); -/// } -/// hexchat_plugin::EAT_NONE -/// } -/// ``` -pub struct Word<'a> { - word: Vec<&'a str> -} - -/// Arguments passed to a hook, until the end of the line. -/// -/// # Examples -/// -/// ``` -/// use hexchat_plugin::{PluginHandle, Word, WordEol, Eat}; -/// -/// fn cmd_foo(ph: &mut PluginHandle, arg: Word, arg_eol: WordEol) -> Eat { -/// if arg.len() < 3 { -/// ph.print("Not enough arguments"); -/// } else { -/// ph.print(&format!("{} {} {}", arg[0], arg[1], arg_eol[2])); -/// } -/// hexchat_plugin::EAT_ALL -/// } -/// -/// fn on_privmsg(ph: &mut PluginHandle, word: Word, word_eol: WordEol) -> Eat { -/// if word_eol.len() > 0 && word[0].starts_with('@') { -/// ph.print("We have message tags!?"); -/// } -/// hexchat_plugin::EAT_NONE -/// } -/// ``` -pub struct WordEol<'a> { - word_eol: Vec<&'a str> -} - /// A safety wrapper to ensure you're working with a valid context. /// /// This mechanism attempts to reduce the likelihood of segfaults. @@ -370,7 +317,7 @@ impl Drop for CommandHookHandle { let b = ((*self.ph).hexchat_unhook)(self.ph, self.hh) as *mut CommandHookUd; // we assume b is not null. this should be safe. // just drop it - mem::drop(Rc::from_raw(b)); + drop(Rc::from_raw(b)); } } } @@ -380,7 +327,7 @@ impl Drop for ServerHookHandle { let b = ((*self.ph).hexchat_unhook)(self.ph, self.hh) as *mut ServerHookUd; // we assume b is not null. this should be safe. // just drop it - mem::drop(Rc::from_raw(b)); + drop(Rc::from_raw(b)); } } } @@ -390,7 +337,7 @@ impl Drop for PrintHookHandle { let b = ((*self.ph).hexchat_unhook)(self.ph, self.hh) as *mut PrintHookUd; // we assume b is not null. this should be safe. // just drop it - mem::drop(Rc::from_raw(b)); + drop(Rc::from_raw(b)); } } } @@ -405,54 +352,8 @@ impl Drop for TimerHookHandle { let b = ((*self.ph).hexchat_unhook)(self.ph, self.hh) as *mut TimerHookUd; // we assume b is not null. this should be safe. // just drop it - mem::drop(Rc::from_raw(b)); - } - } -} - -impl<'a> Word<'a> { - unsafe fn new(word: *const *const libc::c_char) -> Word<'a> { - let mut vec = vec![]; - for i in 1..32 { - let w = *word.offset(i); - if !w.is_null() { - vec.push(CStr::from_ptr(w).to_str().expect("non-utf8 word - broken hexchat")) - } - } - while let Some(&"") = vec.last() { - vec.pop(); + drop(Rc::from_raw(b)); } - Word { word: vec } - } -} - -impl<'a> ops::Deref for Word<'a> { - type Target = [&'a str]; - fn deref(&self) -> &[&'a str] { - &self.word - } -} - -impl<'a> WordEol<'a> { - unsafe fn new(word_eol: *const *const libc::c_char) -> WordEol<'a> { - let mut vec = vec![]; - for i in 1..32 { - let w = *word_eol.offset(i); - if !w.is_null() { - vec.push(CStr::from_ptr(w).to_str().expect("non-utf8 word_eol - broken hexchat")) - } - } - while let Some(&"") = vec.last() { - vec.pop(); - } - WordEol { word_eol: vec } - } -} - -impl<'a> ops::Deref for WordEol<'a> { - type Target = [&'a str]; - fn deref(&self) -> &[&'a str] { - &self.word_eol } } @@ -841,7 +742,7 @@ impl PluginHandle { alive.set(false); // HexChat will automatically free the hook. // we just need to free the userdata. - mem::drop(Rc::from_raw(ud as *const TimerHookUd)); + drop(Rc::from_raw(ud as *const TimerHookUd)); 0 }, Result::Err(e @ _) => { @@ -859,7 +760,7 @@ impl PluginHandle { alive.set(false); // HexChat will automatically free the hook. // we just need to free the userdata. - mem::drop(Rc::from_raw(ud as *const TimerHookUd)); + drop(Rc::from_raw(ud as *const TimerHookUd)); 0 } } diff --git a/src/word.rs b/src/word.rs new file mode 100644 index 0000000..8bcabfc --- /dev/null +++ b/src/word.rs @@ -0,0 +1,130 @@ +// This file is part of Hexchat Plugin API Bindings for Rust +// Copyright (C) 2018, 2021 Soni L. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +use std::ffi::CStr; +use std::ops::Deref; + +/// Arguments passed to a hook, until the next argument. +/// +/// # Examples +/// +/// ```no_run +/// use hexchat_plugin::{PluginHandle, Word, WordEol, Eat}; +/// +/// fn cmd_foo(ph: &mut PluginHandle, arg: Word, arg_eol: WordEol) -> Eat { +/// if arg.len() < 3 { +/// ph.print("Not enough arguments"); +/// } else { +/// ph.print(&format!("{} {} {}", arg[0], arg[1], arg[2])); +/// } +/// hexchat_plugin::EAT_ALL +/// } +/// +/// fn on_privmsg(ph: &mut PluginHandle, word: Word, word_eol: WordEol) -> Eat { +/// if word.len() > 0 && word[0].starts_with('@') { +/// ph.print("We have message tags!?"); +/// } +/// hexchat_plugin::EAT_NONE +/// } +/// ``` +pub struct Word<'a> { + word: Vec<&'a str> +} + +/// Arguments passed to a hook, until the end of the line. +/// +/// # Examples +/// +/// ```no_run +/// use hexchat_plugin::{PluginHandle, Word, WordEol, Eat}; +/// +/// fn cmd_foo(ph: &mut PluginHandle, arg: Word, arg_eol: WordEol) -> Eat { +/// if arg.len() < 3 { +/// ph.print("Not enough arguments"); +/// } else { +/// ph.print(&format!("{} {} {}", arg[0], arg[1], arg_eol[2])); +/// } +/// hexchat_plugin::EAT_ALL +/// } +/// +/// fn on_privmsg(ph: &mut PluginHandle, word: Word, word_eol: WordEol) -> Eat { +/// if word_eol.len() > 0 && word[0].starts_with('@') { +/// ph.print("We have message tags!?"); +/// } +/// hexchat_plugin::EAT_NONE +/// } +/// ``` +pub struct WordEol<'a> { + word_eol: Vec<&'a str> +} + +impl<'a> Word<'a> { + /// Creates a new Word. + /// + /// # Safety + /// + /// Uses raw pointers. + pub(crate) unsafe fn new(word: *const *const libc::c_char) -> Word<'a> { + let mut vec = vec![]; + for i in 1..32 { + let w = *word.offset(i); + if !w.is_null() { + vec.push(CStr::from_ptr(w).to_str().expect("non-utf8 word - broken hexchat")) + } + } + while let Some(&"") = vec.last() { + vec.pop(); + } + Word { word: vec } + } +} + +/// Provides access to the contents of the Word. +impl<'a> Deref for Word<'a> { + type Target = [&'a str]; + fn deref(&self) -> &[&'a str] { + &self.word + } +} + +impl<'a> WordEol<'a> { + /// Creates a new WordEol. + /// + /// # Safety + /// + /// Uses raw pointers. + pub(crate) unsafe fn new(word_eol: *const *const libc::c_char) -> WordEol<'a> { + let mut vec = vec![]; + for i in 1..32 { + let w = *word_eol.offset(i); + if !w.is_null() { + vec.push(CStr::from_ptr(w).to_str().expect("non-utf8 word_eol - broken hexchat")) + } + } + while let Some(&"") = vec.last() { + vec.pop(); + } + WordEol { word_eol: vec } + } +} + +/// Provides access to the contents of the WordEol. +impl<'a> Deref for WordEol<'a> { + type Target = [&'a str]; + fn deref(&self) -> &[&'a str] { + &self.word_eol + } +} |