Remove all runtime expects and unwraps

This commit is contained in:
hodasemi 2019-04-28 14:13:36 +02:00
parent 4aa7edf16a
commit 19b0719719
8 changed files with 242 additions and 175 deletions

View file

@ -57,12 +57,14 @@ impl Value {
T: FromStr, T: FromStr,
{ {
match self { match self {
Value::Array(value_array) => for value_string in value_array { Value::Array(value_array) => {
match value_string.parse::<T>() { for value_string in value_array {
Ok(val) => array.push(val), match value_string.parse::<T>() {
Err(_) => return Err(format!("error parsing value {}", value_string)), Ok(val) => array.push(val),
Err(_) => return Err(format!("error parsing value {}", value_string)),
}
} }
}, }
_ => return Err("key_value has wrong format".to_string()), _ => return Err("key_value has wrong format".to_string()),
}; };
@ -121,7 +123,7 @@ pub fn read_config(file_name: &str) -> Result<HashMap<String, HashMap<String, Va
trimmed_value.remove(0); trimmed_value.remove(0);
trimmed_value.pop(); trimmed_value.pop();
let mut value_split = trimmed_value.split(";"); let value_split = trimmed_value.split(";");
let value_array = value_split.map(|v| v.trim().to_string()).collect(); let value_array = value_split.map(|v| v.trim().to_string()).collect();
if let Some(ref mut section) = current_section { if let Some(ref mut section) = current_section {

View file

@ -33,7 +33,7 @@ impl serenity::framework::standard::Command for List {
let mut output = String::new(); let mut output = String::new();
{ {
let playlist_mutex = self.media.playlist_mut(); let playlist_mutex = self.media.playlist_mut()?;
let playlist = playlist_mutex.borrow(); let playlist = playlist_mutex.borrow();
output += &format!( output += &format!(

View file

@ -31,7 +31,7 @@ impl serenity::framework::standard::Command for Pause {
return Ok(()); return Ok(());
} }
let song_lock = self.media.song_mut(); let song_lock = self.media.song_mut()?;
if let Some(song) = song_lock.borrow_mut().deref_mut() { if let Some(song) = song_lock.borrow_mut().deref_mut() {
let song_clone = song.clone(); let song_clone = song.clone();

View file

@ -4,7 +4,6 @@ use serenity;
use serenity::voice::LockedAudio; use serenity::voice::LockedAudio;
use std::cell::RefCell; use std::cell::RefCell;
use std::fs;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::sync::{Arc, MutexGuard}; use std::sync::{Arc, MutexGuard};
@ -13,7 +12,6 @@ use rand::{seq::SliceRandom, thread_rng};
use super::super::prelude::*; use super::super::prelude::*;
use rusqlite::params; use rusqlite::params;
use rusqlite::types::{FromSql, ToSql};
pub struct Play { pub struct Play {
media: Arc<MediaData>, media: Arc<MediaData>,
@ -77,37 +75,37 @@ impl Play {
ctx: &mut serenity::client::Context, ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
mut source: Vec<Song>, mut source: Vec<Song>,
) { ) -> Result<(), String> {
{ {
let playlist_mutex = self.media.playlist_mut(); let playlist_mutex = self.media.playlist_mut()?;
playlist_mutex.borrow_mut().append(&mut source); playlist_mutex.borrow_mut().append(&mut source);
} }
let manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap(); if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
Self::check_join_channel(&manager_lock, msg);
Self::check_join_channel(&manager_lock, msg); let check_finished = {
let media_clone = self.media.clone();
let channel_id = msg.channel_id;
let manager_lock_clone = manager_lock.clone();
let check_finished = { Arc::new(move || {
let media_clone = self.media.clone(); let callback = match media_clone.next_callback.borrow().deref() {
let channel_id = msg.channel_id; Some(callback) => callback.clone(),
let manager_lock_clone = manager_lock.clone(); None => {
println!("next_callback not set!");
return;
}
};
Arc::new(move || { MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback);
let callback = match media_clone.next_callback.borrow().deref() { })
Some(callback) => callback.clone(), };
None => {
println!("next_callback not set!");
return;
}
};
MediaData::next_song(&media_clone, channel_id, &manager_lock_clone, callback); MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock);
}) }
};
MediaData::start_playing(&self.media, check_finished, msg.channel_id, &manager_lock); Ok(())
//MediaData::start_thread(&self.media, msg.channel_id, &manager_lock);
} }
fn handle_http_request( fn handle_http_request(
@ -115,20 +113,27 @@ impl Play {
ctx: &mut serenity::client::Context, ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
url: &String, url: &String,
) { ) -> Result<(), String> {
let sql = self.media.lock_db(); let sql = self.media.lock_db()?;
let mut stmt = sql let mut stmt = match sql.prepare("SELECT name FROM Vulva3 WHERE link = ?") {
.prepare("SELECT name FROM Vulva3 WHERE link = ?") Ok(statement) => statement,
.unwrap(); Err(_) => return Err("failed preparing data base access".to_string()),
};
let rows = stmt let rows = match stmt.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) {
.query_map(&[url], |row| row.get(0) as rusqlite::Result<String>) Ok(rows) => rows,
.expect("failed requesting db"); Err(_) => return Err("failed querying rows".to_string()),
};
let mut names = Vec::new(); let mut names = Vec::new();
for name_result in rows { for name_result in rows {
names.push(name_result.unwrap()); let name = match name_result {
Ok(name) => name,
Err(_) => return Err("failed getting name from row".to_string()),
};
names.push(name);
} }
if names.len() > 0 { if names.len() > 0 {
@ -138,9 +143,9 @@ impl Play {
ctx, ctx,
msg, msg,
names.iter().map(|n| Song { name: n.clone() }).collect(), names.iter().map(|n| Song { name: n.clone() }).collect(),
); )?;
return; return Ok(());
} }
let source = match youtube_dl(&url) { let source = match youtube_dl(&url) {
@ -152,7 +157,7 @@ impl Play {
.channel_id .channel_id
.say(format!("Error using youtube-dl: {}", why))); .say(format!("Error using youtube-dl: {}", why)));
return; return Ok(());
} }
}; };
@ -165,45 +170,58 @@ impl Play {
for song in &source { for song in &source {
info = format!("{}\n\t{}", info, song.name); info = format!("{}\n\t{}", info, song.name);
sql.execute( if sql
"INSERT INTO Vulva3 (name, link) .execute(
VALUES (?1, ?2)", "INSERT INTO Vulva3 (name, link)
params![song.name, url], VALUES (?1, ?2)",
) params![song.name, url],
.expect("failed inserting song"); )
.is_err()
{
return Err("failed inserting songs into db".to_string());
}
} }
print_error!(msg.channel_id.say(info)); print_error!(msg.channel_id.say(info));
self.append_songs(ctx, msg, source); self.append_songs(ctx, msg, source)?;
Ok(())
} }
fn handle_local_request( fn handle_local_request(
&self, &self,
ctx: &mut serenity::client::Context, ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
) { ) -> Result<(), String> {
//print_error!(self.media.reset(ctx, msg)); let sql = self.media.lock_db()?;
let sql = self.media.lock_db(); let mut stmt = match sql.prepare("SELECT name FROM Vulva3") {
Ok(statement) => statement,
Err(_) => return Err("failed preparing data base access".to_string()),
};
let mut stmt = sql.prepare("SELECT name FROM Vulva3").unwrap(); let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
Ok(rows) => rows,
let rows = stmt Err(_) => return Err("failed querying rows".to_string()),
.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) };
.expect("failed requesting db");
let mut songs = Vec::new(); let mut songs = Vec::new();
for name_result in rows { for name_result in rows {
songs.push(Song { let name = match name_result {
name: name_result.unwrap(), Ok(name) => name,
}); Err(_) => return Err("failed getting name from row".to_string()),
};
songs.push(Song { name });
} }
let mut rng = thread_rng(); let mut rng = thread_rng();
songs.shuffle(&mut rng); songs.shuffle(&mut rng);
self.append_songs(ctx, msg, songs); self.append_songs(ctx, msg, songs)?;
Ok(())
} }
fn handle_song_request( fn handle_song_request(
@ -211,37 +229,44 @@ impl Play {
ctx: &mut serenity::client::Context, ctx: &mut serenity::client::Context,
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
pattern: &str, pattern: &str,
) { ) -> Result<(), String> {
let sql = self.media.lock_db(); let sql = self.media.lock_db()?;
let mut stmt = sql let mut stmt = match sql.prepare(&format!(
.prepare(&format!( "SELECT name FROM Vulva3 WHERE name LIKE '%{}%'",
"SELECT name FROM Vulva3 WHERE name LIKE '%{}%'", pattern
pattern )) {
)) Ok(statement) => statement,
.unwrap(); Err(_) => return Err("failed preparing data base access".to_string()),
};
let rows = stmt let rows = match stmt.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) {
.query_map(params![], |row| row.get(0) as rusqlite::Result<String>) Ok(rows) => rows,
.expect("failed requesting db"); Err(_) => return Err("failed querying rows".to_string()),
};
let mut songs = Vec::new(); let mut songs = Vec::new();
for name_result in rows { for name_result in rows {
songs.push(Song { let name = match name_result {
name: name_result.unwrap(), Ok(name) => name,
}); Err(_) => return Err("failed getting name from row".to_string()),
};
songs.push(Song { name });
} }
if !songs.is_empty() { if !songs.is_empty() {
let mut rng = thread_rng(); let mut rng = thread_rng();
songs.shuffle(&mut rng); songs.shuffle(&mut rng);
self.append_songs(ctx, msg, songs); self.append_songs(ctx, msg, songs)?;
} else { } else {
print_error!(msg print_error!(msg
.channel_id .channel_id
.say(format!("no song found with pattern {}", pattern))); .say(format!("no song found with pattern {}", pattern)));
} }
Ok(())
} }
} }
@ -262,7 +287,7 @@ impl serenity::framework::standard::Command for Play {
} }
if args.len() == 0 { if args.len() == 0 {
if !Self::check_for_continue(self.media.song_mut()) { if !Self::check_for_continue(self.media.song_mut()?) {
print_error!(msg.channel_id.say("Must provide a URL to a video or audio")); print_error!(msg.channel_id.say("Must provide a URL to a video or audio"));
} }
} else if args.len() == 1 { } else if args.len() == 1 {
@ -273,11 +298,11 @@ impl serenity::framework::standard::Command for Play {
}; };
if arg == "--local" { if arg == "--local" {
self.handle_local_request(ctx, msg); self.handle_local_request(ctx, msg)?;
} else if arg.starts_with("http") { } else if arg.starts_with("http") {
self.handle_http_request(ctx, msg, &arg); self.handle_http_request(ctx, msg, &arg)?;
} else { } else {
self.handle_song_request(ctx, msg, &arg); self.handle_song_request(ctx, msg, &arg)?;
} }
} else { } else {
print_error!(msg.channel_id.say("Unsupported argument list")); print_error!(msg.channel_id.say("Unsupported argument list"));

View file

@ -27,13 +27,16 @@ impl serenity::framework::standard::Command for Remove {
) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> {
// (1) // (1)
let song_name = self.media.name_mut(); let song_name = self.media.name_mut()?;
let name: String = song_name.borrow().clone(); let name: String = song_name.borrow().clone();
let sql = self.media.lock_db(); let sql = self.media.lock_db()?;
sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name]) if let Err(_) = sql.execute("DELETE FROM Vulva3 WHERE name = ?", params![name]) {
.expect("failed deleting song"); return Err(serenity::framework::standard::CommandError(
"failed executing sql delete".to_string(),
));
}
if !name.is_empty() { if !name.is_empty() {
match fs::remove_file(&name) { match fs::remove_file(&name) {

View file

@ -31,61 +31,60 @@ impl serenity::framework::standard::Command for Skip {
return Ok(()); return Ok(());
} }
let mut manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap(); if let Some(mut manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
let mut manager = manager_lock.lock();
let mut manager = manager_lock.lock(); let guild_id = match guild_id(msg.channel_id) {
Some(id) => id,
None => {
println!("error getting guild id");
print_error!(msg.channel_id.say("error getting guild id"));
let guild_id = match guild_id(msg.channel_id) { return Ok(());
Some(id) => id, }
None => { };
println!("error getting guild id");
print_error!(msg.channel_id.say("error getting guild id"));
return Ok(()); if let Some(handler) = handler(guild_id, &mut manager) {
} let playlist_mutex = self.media.playlist_mut()?;
}; let mut playlist = playlist_mutex.borrow_mut();
if let Some(handler) = handler(guild_id, &mut manager) { let song_mutex = self.media.song_mut()?;
let playlist_mutex = self.media.playlist_mut(); let mut song = song_mutex.borrow_mut();
let mut playlist = playlist_mutex.borrow_mut();
let song_mutex = self.media.song_mut(); if playlist.is_empty() {
let mut song = song_mutex.borrow_mut(); print_error!(msg
.channel_id
.say("playlist is empty, no next song available"));
if playlist.is_empty() { return Ok(());
print_error!( } else {
msg.channel_id let first = playlist.remove(0);
.say("playlist is empty, no next song available")
);
return Ok(()); handler.stop();
} else {
let first = playlist.remove(0);
handler.stop(); let source = match ffmpeg(first.name.clone()) {
Ok(mpeg) => mpeg,
Err(_) => {
playlist.clear();
*song = None;
let source = match ffmpeg(first.name.clone()) { return Ok(());
Ok(mpeg) => mpeg, }
Err(_) => { };
playlist.clear();
*song = None;
return Ok(()); match self.media.next_callback.borrow().as_ref() {
Some(callback) => {
*song =
Some(handler.play_returning_and_callback(source, callback.clone()));
let song_name = self.media.name_mut()?;
*song_name.borrow_mut() = first.name.clone();
print_error!(msg
.channel_id
.say(format!("Skipped current song, now playing: {}", first.name)));
}
None => println!("error getting callback from media"),
} }
};
match self.media.next_callback.borrow().as_ref() {
Some(callback) => {
*song = Some(handler.play_returning_and_callback(source, callback.clone()));
let song_name = self.media.name_mut();
*song_name.borrow_mut() = first.name.clone();
print_error!(
msg.channel_id
.say(format!("Skipped current song, now playing: {}", first.name))
);
}
None => println!("error getting callback from media"),
} }
} }
} }

View file

@ -8,7 +8,6 @@ use std::sync::{Arc, Mutex, MutexGuard};
use super::prelude::*; use super::prelude::*;
use rusqlite::types::ToSql;
use rusqlite::{params, Connection}; use rusqlite::{params, Connection};
pub struct Song { pub struct Song {
@ -61,17 +60,17 @@ impl MediaData {
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
) -> Result<(), String> { ) -> Result<(), String> {
{ {
let playlist = self.playlist_mut(); let playlist = self.playlist_mut()?;
playlist.borrow_mut().clear(); playlist.borrow_mut().clear();
} }
{ {
let song = self.song_mut(); let song = self.song_mut()?;
*song.borrow_mut() = None; *song.borrow_mut() = None;
} }
{ {
let name = self.name_mut(); let name = self.name_mut()?;
*name.borrow_mut() = String::new(); *name.borrow_mut() = String::new();
} }
@ -79,8 +78,7 @@ impl MediaData {
*self.next_callback.borrow_mut() = None; *self.next_callback.borrow_mut() = None;
} }
{ if let Some(manager_lock) = ctx.data.lock().get::<VoiceManager>().cloned() {
let manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap();
let mut manager = manager_lock.lock(); let mut manager = manager_lock.lock();
let guild_id = match guild_id(msg.channel_id) { let guild_id = match guild_id(msg.channel_id) {
@ -105,20 +103,32 @@ impl MediaData {
Ok(()) Ok(())
} }
pub fn lock_db(&self) -> MutexGuard<Connection> { pub fn lock_db(&self) -> Result<MutexGuard<Connection>, String> {
self.sql_data_base.lock().unwrap() match self.sql_data_base.lock() {
Ok(sql) => Ok(sql),
Err(_) => Err("failed locking db".to_string()),
}
} }
pub fn song_mut(&self) -> MutexGuard<RefCell<Option<LockedAudio>>> { pub fn song_mut(&self) -> Result<MutexGuard<RefCell<Option<LockedAudio>>>, String> {
self.current_song.lock().unwrap() match self.current_song.lock() {
Ok(sql) => Ok(sql),
Err(_) => Err("failed locking current song".to_string()),
}
} }
pub fn playlist_mut(&self) -> MutexGuard<RefCell<Vec<Song>>> { pub fn playlist_mut(&self) -> Result<MutexGuard<RefCell<Vec<Song>>>, String> {
self.playlist.lock().unwrap() match self.playlist.lock() {
Ok(sql) => Ok(sql),
Err(_) => Err("failed locking playlist".to_string()),
}
} }
pub fn name_mut(&self) -> MutexGuard<RefCell<String>> { pub fn name_mut(&self) -> Result<MutexGuard<RefCell<String>>, String> {
self.song_name.lock().unwrap() match self.song_name.lock() {
Ok(sql) => Ok(sql),
Err(_) => Err("failed locking current song name".to_string()),
}
} }
pub fn start_playing( pub fn start_playing(
@ -131,7 +141,14 @@ impl MediaData {
) { ) {
// check if there is already playing // check if there is already playing
let already_started = { let already_started = {
let song_lock = mediadata.song_mut(); let song_lock = match mediadata.song_mut() {
Ok(song) => song,
Err(msg) => {
println!("{}", msg);
return;
}
};
let song = song_lock.borrow(); let song = song_lock.borrow();
song.is_some() song.is_some()
}; };
@ -175,13 +192,31 @@ impl MediaData {
} }
}; };
let playlist_lock = mediadata.playlist_mut(); let playlist_lock = match mediadata.playlist_mut() {
Ok(playlist) => playlist,
Err(msg) => {
println!("{}", msg);
return;
}
};
let mut playlist = playlist_lock.borrow_mut(); let mut playlist = playlist_lock.borrow_mut();
let song_name_lock = mediadata.name_mut(); let song_name_lock = match mediadata.name_mut() {
Ok(name) => name,
Err(msg) => {
println!("{}", msg);
return;
}
};
let mut name = song_name_lock.borrow_mut(); let mut name = song_name_lock.borrow_mut();
let song_lock = mediadata.song_mut(); let song_lock = match mediadata.song_mut() {
Ok(song) => song,
Err(msg) => {
println!("{}", msg);
return;
}
};
let mut song = song_lock.borrow_mut(); let mut song = song_lock.borrow_mut();
if playlist.is_empty() { if playlist.is_empty() {

View file

@ -32,35 +32,38 @@ pub fn channel_contains_author(
msg: &serenity::model::channel::Message, msg: &serenity::model::channel::Message,
) -> bool { ) -> bool {
let (guild_id, voice_channel_id_bot) = { let (guild_id, voice_channel_id_bot) = {
let manager_lock = ctx.data.lock().get::<VoiceManager>().cloned().unwrap(); match ctx.data.lock().get::<VoiceManager>().cloned() {
Some(manager_lock) => {
let mut manager = manager_lock.lock();
let guild_id = match guild_id(msg.channel_id) {
Some(guild_id) => guild_id,
None => {
println!("error getting guild_id");
return true;
}
};
let mut manager = manager_lock.lock(); let handler = match handler(guild_id, &mut manager) {
let guild_id = match guild_id(msg.channel_id) { Some(handler) => handler,
Some(guild_id) => guild_id, None => {
None => { println!("error getting handler");
println!("error getting guild_id"); return true;
return true; }
};
(
guild_id,
match handler.channel_id {
Some(id) => id,
None => {
println!("error getting channel_id for bot");
return true;
}
},
)
} }
}; None => return false,
}
let handler = match handler(guild_id, &mut manager) {
Some(handler) => handler,
None => {
println!("error getting handler");
return true;
}
};
(
guild_id,
match handler.channel_id {
Some(id) => id,
None => {
println!("error getting channel_id for bot");
return true;
}
},
)
}; };
let author = &msg.author; let author = &msg.author;