remove all unsafe usage

This commit is contained in:
Stephan Dilly 2020-03-31 01:26:22 +02:00
parent 80b5a53662
commit f8f05d6c31
2 changed files with 46 additions and 10 deletions

View File

@ -2,12 +2,16 @@
![CI][s0] [![crates][s1]][l1] ![MIT][s2] [![LOC][s3]][l3]
![CI][s0] [![crates][s1]][l1] ![MIT][s2] [![LOC][s3]][l3] [![UNSAFE][s4]][l4]
[s0]: https://github.com/extrawurst/gitui/workflows/CI/badge.svg
[s1]: https://img.shields.io/crates/v/gitui.svg
[l1]: https://crates.io/crates/gitui
[s2]: https://img.shields.io/badge/license-MIT-blue.svg
[s3]: https://tokei.rs/b1/github/extrawurst/gitui
[l3]: https://github.com/extrawurst/gitui
[s4]: https://img.shields.io/badge/unsafe-forbidden-success.svg
[l4]: https://github.com/rust-secure-code/safety-dance/
blazing fast terminal-ui for git written in rust

View File

@ -1,6 +1,5 @@
#![deny(clippy::all)]
//TODO: the crossbeam::select macro uses unsafe :(
// #![forbid(unsafe_code)]
#![forbid(unsafe_code)]
mod app;
mod components;
@ -10,8 +9,9 @@ mod strings;
mod ui;
use crate::{app::App, poll::QueueEvent};
use asyncgit::AsyncNotification;
use backtrace::Backtrace;
use crossbeam_channel::{select, tick, unbounded};
use crossbeam_channel::{tick, unbounded, Receiver, Select};
use crossterm::{
terminal::{
disable_raw_mode, enable_raw_mode, EnterAlternateScreen,
@ -24,7 +24,12 @@ use log::error;
use scopeguard::defer;
use scopetime::scope_time;
use simplelog::*;
use std::{env, fs, fs::File, io, panic, time::Duration};
use std::{
env, fs,
fs::File,
io, panic,
time::{Duration, Instant},
};
use tui::{backend::CrosstermBackend, Terminal};
static TICK_INTERVAL: Duration = Duration::from_secs(5);
@ -54,12 +59,8 @@ fn main() -> Result<()> {
app.update();
loop {
let mut events: Vec<QueueEvent> = Vec::new();
select! {
recv(rx_input) -> inputs => events.append(&mut inputs.unwrap()),
recv(rx_git) -> ev => events.push(QueueEvent::GitEvent(ev.unwrap())),
recv(ticker) -> _ => events.push(QueueEvent::Tick),
}
let events: Vec<QueueEvent> =
select_event(&rx_input, &rx_git, &ticker);
{
scope_time!("loop");
@ -83,6 +84,37 @@ fn main() -> Result<()> {
Ok(())
}
fn select_event(
rx_input: &Receiver<Vec<QueueEvent>>,
rx_git: &Receiver<AsyncNotification>,
rx_ticker: &Receiver<Instant>,
) -> Vec<QueueEvent> {
let mut events: Vec<QueueEvent> = Vec::new();
let mut sel = Select::new();
sel.recv(rx_input);
sel.recv(rx_git);
sel.recv(rx_ticker);
let oper = sel.select();
let index = oper.index();
match index {
0 => oper.recv(rx_input).map(|inputs| events.extend(inputs)),
1 => oper
.recv(rx_git)
.map(|ev| events.push(QueueEvent::GitEvent(ev))),
2 => oper
.recv(rx_ticker)
.map(|_| events.push(QueueEvent::Tick)),
_ => Ok(()),
}
.unwrap();
events
}
fn start_terminal<W: Write>(
buf: W,
) -> io::Result<Terminal<CrosstermBackend<W>>> {