1
1
mirror of https://github.com/wez/wezterm.git synced 2025-01-08 23:17:36 +03:00

failure -> anyhow + thiserror

This commit is contained in:
Wez Furlong 2019-12-14 21:43:05 -08:00
parent 16cfe58d50
commit 9a2c7a1485
94 changed files with 723 additions and 723 deletions

View File

@ -13,6 +13,8 @@ embed-resource = "1.3"
[dependencies]
allsorts = "0.1"
anyhow = "1.0"
thiserror = "1.0"
base64 = "0.10"
base91 = { path = "base91" }
bitflags = "1.0"
@ -20,7 +22,7 @@ crossbeam-channel = "0.3"
dirs = "1.0"
downcast-rs = "1.0"
euclid = "0.20"
filedescriptor = "0.5"
filedescriptor = "0.6"
pretty_env_logger = "0.3"
failure = "0.1"
failure_derive = "0.1"

View File

@ -1,9 +1,9 @@
[package]
authors = ["Wez Furlong <wez@wezfurlong.org>"]
name = "promise"
version = "0.1.0"
version = "0.2.0"
edition = "2018"
[dependencies]
failure = "0.1"
failure_derive = "0.1"
anyhow = "1.0"
thiserror = "1.0"

View File

@ -1,14 +1,14 @@
use failure::{Error, Fallible};
use failure_derive::*;
use anyhow::{bail, Error, Result as Fallible};
use std::pin::Pin;
use std::sync::{Arc, Condvar, Mutex};
use std::task::{Context, Poll};
use thiserror::*;
type NextFunc<T> = Box<dyn FnOnce(Fallible<T>) + Send>;
pub type SpawnFunc = Box<dyn FnOnce() + Send>;
#[derive(Debug, Fail)]
#[fail(display = "Promise was dropped before completion")]
#[derive(Debug, Error)]
#[error("Promise was dropped before completion")]
pub struct BrokenPromise {}
pub trait BasicExecutor {
@ -214,7 +214,7 @@ impl<T: Send + 'static> Future<T> {
}
}
FutureState::Ready(result) => result,
FutureState::Resolved => failure::bail!("Future is already Resolved"),
FutureState::Resolved => bail!("Future is already Resolved"),
}
}
@ -335,7 +335,7 @@ impl<T: Send + 'static> std::future::Future for Future<T> {
#[cfg(test)]
mod test {
use super::*;
use failure::{err_msg, format_err};
use anyhow::anyhow;
#[test]
fn basic_promise() {
let mut p = Promise::new();
@ -377,8 +377,8 @@ mod test {
let f: Future<usize> = p
.get_future()
.unwrap()
.map(|_value| Err(err_msg("boo")))
.map_err(|err| Err(format_err!("whoops: {}", err)));
.map(|_value| Err(anyhow!("boo")))
.map_err(|err| Err(anyhow!("whoops: {}", err)));
p.ok(1);
assert_eq!(format!("{}", f.wait().unwrap_err()), "whoops: boo");
}

View File

@ -9,9 +9,8 @@ license = "MIT"
documentation = "https://docs.rs/portable-pty"
[dependencies]
failure = "0.1"
failure_derive = "0.1"
filedescriptor = "0.5"
anyhow = "1.0"
filedescriptor = "0.6"
log = "0.4"
libc = "0.2"
shell-words = "0.1"

View File

@ -1,7 +1,5 @@
#[cfg(windows)]
use failure::{ensure, Error};
#[cfg(unix)]
use failure::{format_err, Fallible};
use anyhow::Context;
#[cfg(feature = "serde_support")]
use serde_derive::*;
use std::ffi::{OsStr, OsString};
@ -81,12 +79,12 @@ impl CommandBuilder {
}
#[cfg(feature = "ssh")]
pub(crate) fn as_unix_command_line(&self) -> failure::Fallible<String> {
pub(crate) fn as_unix_command_line(&self) -> anyhow::Result<String> {
let mut strs = vec![];
for arg in &self.args {
let s = arg
.to_str()
.ok_or_else(|| failure::err_msg("argument cannot be represented as utf8"))?;
.ok_or_else(|| anyhow::anyhow!("argument cannot be represented as utf8"))?;
strs.push(s);
}
Ok(shell_words::join(strs))
@ -96,7 +94,7 @@ impl CommandBuilder {
#[cfg(unix)]
impl CommandBuilder {
/// Convert the CommandBuilder to a `std::process::Command` instance.
pub(crate) fn as_command(&self) -> Fallible<std::process::Command> {
pub(crate) fn as_command(&self) -> anyhow::Result<std::process::Command> {
let mut cmd = if self.is_default_prog() {
let mut cmd = std::process::Command::new(&Self::get_shell()?);
cmd.current_dir(Self::get_home_dir()?);
@ -117,7 +115,7 @@ impl CommandBuilder {
/// Determine which shell to run.
/// We take the contents of the $SHELL env var first, then
/// fall back to looking it up from the password database.
fn get_shell() -> Fallible<String> {
fn get_shell() -> anyhow::Result<String> {
std::env::var("SHELL").or_else(|_| {
let ent = unsafe { libc::getpwuid(libc::getuid()) };
@ -130,12 +128,12 @@ impl CommandBuilder {
shell
.to_str()
.map(str::to_owned)
.map_err(|e| format_err!("failed to resolve shell: {:?}", e))
.context("failed to resolve shell")
}
})
}
fn get_home_dir() -> Fallible<String> {
fn get_home_dir() -> anyhow::Result<String> {
std::env::var("HOME").or_else(|_| {
let ent = unsafe { libc::getpwuid(libc::getuid()) };
@ -147,7 +145,7 @@ impl CommandBuilder {
let home = unsafe { CStr::from_ptr((*ent).pw_dir) };
home.to_str()
.map(str::to_owned)
.map_err(|e| format_err!("failed to resolve home dir: {:?}", e))
.context("failed to resolve home dir")
}
})
}
@ -211,7 +209,7 @@ impl CommandBuilder {
block
}
pub(crate) fn cmdline(&self) -> Result<(Vec<u16>, Vec<u16>), Error> {
pub(crate) fn cmdline(&self) -> anyhow::Result<(Vec<u16>, Vec<u16>)> {
let mut cmdline = Vec::<u16>::new();
let exe = if self.is_default_prog() {
@ -229,7 +227,7 @@ impl CommandBuilder {
for arg in self.args.iter().skip(1) {
cmdline.push(' ' as u16);
ensure!(
anyhow::ensure!(
!arg.encode_wide().any(|c| c == 0),
"invalid encoding for command line argument {:?}",
arg

View File

@ -7,7 +7,7 @@
//!
//! ```no_run
//! use portable_pty::{CommandBuilder, PtySize, PtySystemSelection};
//! use failure::Error;
//! use anyhow::Error;
//!
//! // Use the native pty implementation for the system
//! let pty_system = PtySystemSelection::default().get()?;
@ -43,7 +43,7 @@
//! `ssh::SshSession` type that can wrap an established ssh
//! session with an implementation of `PtySystem`, allowing
//! you to use the same pty interface with remote ptys.
use failure::{bail, format_err, Error, Fallible};
use anyhow::{anyhow, bail, Error};
#[cfg(feature = "serde_support")]
use serde_derive::*;
use std::io::Result as IoResult;
@ -166,7 +166,7 @@ pub trait PtySystem {
/// Create a new Pty instance with the window size set to the specified
/// dimensions. Returns a (master, slave) Pty pair. The master side
/// is used to drive the slave side.
fn openpty(&self, size: PtySize) -> Fallible<PtyPair>;
fn openpty(&self, size: PtySize) -> anyhow::Result<PtyPair>;
}
impl Child for std::process::Child {
@ -208,7 +208,7 @@ impl PtySystemSelection {
/// Construct an instance of PtySystem described by the enum value.
/// Windows specific enum variants result in an error.
#[cfg(unix)]
pub fn get(self) -> Fallible<Box<dyn PtySystem>> {
pub fn get(self) -> anyhow::Result<Box<dyn PtySystem>> {
match self {
PtySystemSelection::Unix => Ok(Box::new(unix::UnixPtySystem {})),
_ => bail!("{:?} not available on unix", self),
@ -218,7 +218,7 @@ impl PtySystemSelection {
/// Construct an instance of PtySystem described by the enum value.
/// Unix specific enum variants result in an error.
#[cfg(windows)]
pub fn get(&self) -> Fallible<Box<dyn PtySystem>> {
pub fn get(&self) -> anyhow::Result<Box<dyn PtySystem>> {
match self {
PtySystemSelection::ConPty => Ok(Box::new(win::conpty::ConPtySystem {})),
PtySystemSelection::WinPty => Ok(Box::new(win::winpty::WinPtySystem {})),
@ -244,7 +244,7 @@ impl std::str::FromStr for PtySystemSelection {
"unix" => Ok(PtySystemSelection::Unix),
"winpty" => Ok(PtySystemSelection::WinPty),
"conpty" => Ok(PtySystemSelection::ConPty),
_ => Err(format_err!(
_ => Err(anyhow!(
"{} is not a valid PtySystemSelection variant, possible values are {:?}",
s,
PtySystemSelection::variants()

View File

@ -6,7 +6,7 @@
//! On most (all?) systems, attempting to open multiple instances of
//! the same serial port will fail.
use crate::{Child, CommandBuilder, ExitStatus, MasterPty, PtyPair, PtySize, PtySystem, SlavePty};
use failure::{format_err, Fallible};
use anyhow::{ensure, Context};
use filedescriptor::FileDescriptor;
use serial::{BaudRate, CharSize, FlowControl, Parity, SerialPort, StopBits, SystemPort};
use std::ffi::{OsStr, OsString};
@ -60,9 +60,9 @@ impl SerialTty {
}
impl PtySystem for SerialTty {
fn openpty(&self, _size: PtySize) -> Fallible<PtyPair> {
fn openpty(&self, _size: PtySize) -> anyhow::Result<PtyPair> {
let mut port = serial::open(&self.port)
.map_err(|e| format_err!("openpty on serial port {:?}: {}", self.port, e))?;
.with_context(|| format!("openpty on serial port {:?}", self.port))?;
port.reconfigure(&|settings| {
settings.set_baud_rate(self.baud)?;
@ -95,8 +95,8 @@ struct Slave {
}
impl SlavePty for Slave {
fn spawn_command(&self, cmd: CommandBuilder) -> Fallible<Box<dyn Child>> {
failure::ensure!(
fn spawn_command(&self, cmd: CommandBuilder) -> anyhow::Result<Box<dyn Child>> {
ensure!(
cmd.is_default_prog(),
"can only use default prog commands with serial tty implementations"
);
@ -151,17 +151,17 @@ impl Write for Master {
}
impl MasterPty for Master {
fn resize(&self, _size: PtySize) -> Fallible<()> {
fn resize(&self, _size: PtySize) -> anyhow::Result<()> {
// Serial ports have no concept of size
Ok(())
}
fn get_size(&self) -> Fallible<PtySize> {
fn get_size(&self) -> anyhow::Result<PtySize> {
// Serial ports have no concept of size
Ok(PtySize::default())
}
fn try_clone_reader(&self) -> Fallible<Box<dyn std::io::Read + Send>> {
fn try_clone_reader(&self) -> anyhow::Result<Box<dyn std::io::Read + Send>> {
// We rely on the fact that SystemPort implements the traits
// that expose the underlying file descriptor, and that direct
// reads from that return the raw data that we want

View File

@ -5,7 +5,7 @@
//! initiate a connection somewhere and to authenticate that session
//! before we can get to a point where `openpty` will be able to run.
use crate::{Child, CommandBuilder, ExitStatus, MasterPty, PtyPair, PtySize, PtySystem, SlavePty};
use failure::{format_err, Fallible};
use anyhow::Context;
use filedescriptor::AsRawSocketDescriptor;
use ssh2::{Channel, Session};
use std::collections::HashMap;
@ -79,7 +79,7 @@ impl SshSession {
}
impl PtySystem for SshSession {
fn openpty(&self, size: PtySize) -> Fallible<PtyPair> {
fn openpty(&self, size: PtySize) -> anyhow::Result<PtyPair> {
let mut inner = self.inner.lock().unwrap();
let mut channel = inner.session.channel_session()?;
channel.handle_extended_data(ssh2::ExtendedData::Merge)?;
@ -154,7 +154,7 @@ impl Write for SshMaster {
}
impl MasterPty for SshMaster {
fn resize(&self, size: PtySize) -> Fallible<()> {
fn resize(&self, size: PtySize) -> anyhow::Result<()> {
self.pty.with_pty(|pty| {
pty.channel.request_pty_size(
size.cols.into(),
@ -167,11 +167,11 @@ impl MasterPty for SshMaster {
})
}
fn get_size(&self) -> Fallible<PtySize> {
fn get_size(&self) -> anyhow::Result<PtySize> {
Ok(self.pty.with_pty(|pty| pty.size))
}
fn try_clone_reader(&self) -> Fallible<Box<dyn std::io::Read + Send>> {
fn try_clone_reader(&self) -> anyhow::Result<Box<dyn std::io::Read + Send>> {
Ok(Box::new(SshReader {
pty: self.pty.clone(),
}))
@ -183,12 +183,12 @@ struct SshSlave {
}
impl SlavePty for SshSlave {
fn spawn_command(&self, cmd: CommandBuilder) -> Fallible<Box<dyn Child>> {
fn spawn_command(&self, cmd: CommandBuilder) -> anyhow::Result<Box<dyn Child>> {
self.pty.with_channel(|channel| {
for (key, val) in cmd.iter_env_as_str() {
channel
.setenv(key, val)
.map_err(|e| format_err!("ssh: setenv {}={} failed: {}", key, val, e))?;
.with_context(|| format!("ssh: setenv {}={} failed", key, val))?;
}
if cmd.is_default_prog() {

View File

@ -1,7 +1,7 @@
//! Working with pseudo-terminals
use crate::{Child, CommandBuilder, MasterPty, PtyPair, PtySize, PtySystem, SlavePty};
use failure::{bail, Error, Fallible};
use anyhow::{bail, Error};
use filedescriptor::FileDescriptor;
use libc::{self, winsize};
use std::io;
@ -13,7 +13,7 @@ use std::ptr;
pub struct UnixPtySystem {}
impl PtySystem for UnixPtySystem {
fn openpty(&self, size: PtySize) -> Fallible<PtyPair> {
fn openpty(&self, size: PtySize) -> anyhow::Result<PtyPair> {
let mut master: RawFd = -1;
let mut slave: RawFd = -1;

View File

@ -9,16 +9,16 @@ pub struct DaemonOptions {
pub stderr: Option<PathBuf>,
}
fn open_log(path: PathBuf) -> Fallible<File> {
fn open_log(path: PathBuf) -> anyhow::Result<File> {
create_user_owned_dirs(
path.parent()
.ok_or_else(|| format_err!("path {} has no parent dir!?", path.display()))?,
.ok_or_else(|| anyhow!("path {} has no parent dir!?", path.display()))?,
)?;
let mut options = OpenOptions::new();
options.write(true).create(true).append(true);
options
.open(&path)
.map_err(|e| format_err!("failed to open log stream: {}: {}", path.display(), e))
.map_err(|e| anyhow!("failed to open log stream: {}: {}", path.display(), e))
}
impl DaemonOptions {
@ -47,12 +47,12 @@ impl DaemonOptions {
}
#[cfg_attr(windows, allow(dead_code))]
pub fn open_stdout(&self) -> Fallible<File> {
pub fn open_stdout(&self) -> anyhow::Result<File> {
open_log(self.stdout())
}
#[cfg_attr(windows, allow(dead_code))]
pub fn open_stderr(&self) -> Fallible<File> {
pub fn open_stderr(&self) -> anyhow::Result<File> {
open_log(self.stderr())
}
}

View File

@ -1,5 +1,5 @@
use crate::keyassignment::{KeyAssignment, SpawnTabDomain};
use failure::{format_err, Error};
use anyhow::{anyhow, Error};
use serde::{Deserialize, Deserializer};
use serde_derive::*;
use termwiz::input::{KeyCode, Modifiers};
@ -26,7 +26,7 @@ impl std::convert::TryInto<KeyAssignment> for &Key {
let arg = self
.arg
.as_ref()
.ok_or_else(|| format_err!("missing arg for {:?}", self))?;
.ok_or_else(|| anyhow!("missing arg for {:?}", self))?;
if let Ok(id) = arg.parse() {
KeyAssignment::SpawnTab(SpawnTabDomain::Domain(id))
@ -48,19 +48,19 @@ impl std::convert::TryInto<KeyAssignment> for &Key {
KeyAction::ActivateTab => KeyAssignment::ActivateTab(
self.arg
.as_ref()
.ok_or_else(|| format_err!("missing arg for {:?}", self))?
.ok_or_else(|| anyhow!("missing arg for {:?}", self))?
.parse()?,
),
KeyAction::ActivateTabRelative => KeyAssignment::ActivateTabRelative(
self.arg
.as_ref()
.ok_or_else(|| format_err!("missing arg for {:?}", self))?
.ok_or_else(|| anyhow!("missing arg for {:?}", self))?
.parse()?,
),
KeyAction::SendString => KeyAssignment::SendString(
self.arg
.as_ref()
.ok_or_else(|| format_err!("missing arg for {:?}", self))?
.ok_or_else(|| anyhow!("missing arg for {:?}", self))?
.to_owned(),
),
KeyAction::ReloadConfiguration => KeyAssignment::ReloadConfiguration,

View File

@ -6,7 +6,7 @@ use crate::font::rasterizer::FontRasterizerSelection;
use crate::font::shaper::FontShaperSelection;
use crate::frontend::FrontEndSelection;
use crate::keyassignment::KeyAssignment;
use failure::{bail, err_msg, format_err, Error, Fallible};
use anyhow::{anyhow, bail, Context, Error};
use lazy_static::lazy_static;
use portable_pty::{CommandBuilder, PtySystemSelection};
use serde_derive::*;
@ -67,7 +67,7 @@ pub fn reload() {
/// return it, otherwise return the current configuration
pub fn configuration_result() -> Result<ConfigHandle, Error> {
if let Some(error) = CONFIG.get_error() {
failure::bail!("{}", error);
bail!("{}", error);
}
Ok(CONFIG.get())
}
@ -153,7 +153,7 @@ impl ConfigInner {
}
}
Err(err) => {
let err = err.to_string();
let err = err.to_string().to_string();
log::error!("While reloading configuration: {}", err);
#[cfg(not(windows))]
@ -465,7 +465,7 @@ impl Config {
file.read_to_string(&mut s)?;
let cfg: Self = toml::from_str(&s)
.map_err(|e| format_err!("Error parsing TOML from {}: {}", p.display(), e))?;
.with_context(|| format!("Error parsing TOML from {}", p.display()))?;
// Compute but discard the key bindings here so that we raise any
// problems earlier than we use them.
@ -480,7 +480,7 @@ impl Config {
Self::default().compute_extra_defaults(None)
}
pub fn key_bindings(&self) -> Fallible<HashMap<(KeyCode, Modifiers), KeyAssignment>> {
pub fn key_bindings(&self) -> anyhow::Result<HashMap<(KeyCode, Modifiers), KeyAssignment>> {
let mut map = HashMap::new();
for k in &self.keys {
@ -611,6 +611,6 @@ fn compute_runtime_dir() -> Result<PathBuf, Error> {
return Ok(runtime.join("wezterm"));
}
let home = dirs::home_dir().ok_or_else(|| err_msg("can't find home dir"))?;
let home = dirs::home_dir().ok_or_else(|| anyhow!("can't find home dir"))?;
Ok(home.join(".local/share/wezterm"))
}

View File

@ -51,7 +51,7 @@ impl UnixDomain {
vec![UnixDomain::default()]
}
pub fn serve_command(&self) -> Fallible<Vec<OsString>> {
pub fn serve_command(&self) -> anyhow::Result<Vec<OsString>> {
match self.serve_command.as_ref() {
Some(cmd) => Ok(cmd.iter().map(Into::into).collect()),
None => Ok(vec![

View File

@ -1,7 +1,7 @@
//! Slightly higher level helper for fontconfig
#![allow(clippy::mutex_atomic)]
use failure::{ensure, err_msg, format_err, Error};
use anyhow::{anyhow, ensure, Error};
pub use fontconfig::*;
use std::ffi::{CStr, CString};
use std::fmt;
@ -121,12 +121,12 @@ impl FcResultWrap {
// the compiler thinks we defined these globals, when all
// we did was import them from elsewhere
match self.0 {
fontconfig::FcResultMatch => err_msg("FcResultMatch"),
fontconfig::FcResultNoMatch => err_msg("FcResultNoMatch"),
fontconfig::FcResultTypeMismatch => err_msg("FcResultTypeMismatch"),
fontconfig::FcResultNoId => err_msg("FcResultNoId"),
fontconfig::FcResultOutOfMemory => err_msg("FcResultOutOfMemory"),
_ => format_err!("FcResult holds invalid value {}", self.0),
fontconfig::FcResultMatch => anyhow!("FcResultMatch"),
fontconfig::FcResultNoMatch => anyhow!("FcResultNoMatch"),
fontconfig::FcResultTypeMismatch => anyhow!("FcResultTypeMismatch"),
fontconfig::FcResultNoId => anyhow!("FcResultNoId"),
fontconfig::FcResultOutOfMemory => anyhow!("FcResultOutOfMemory"),
_ => anyhow!("FcResult holds invalid value {}", self.0),
}
}

View File

@ -1,7 +1,7 @@
//! Higher level freetype bindings
use crate::font::locator::FontDataHandle;
use failure::{bail, format_err, Error, Fallible, ResultExt};
use anyhow::{anyhow, bail, Context};
pub use freetype::*;
use std::ptr;
@ -11,11 +11,11 @@ pub fn succeeded(error: FT_Error) -> bool {
}
/// Translate an error and value into a result
fn ft_result<T>(err: FT_Error, t: T) -> Result<T, Error> {
fn ft_result<T>(err: FT_Error, t: T) -> anyhow::Result<T> {
if succeeded(err) {
Ok(t)
} else {
Err(format_err!("FreeType error {:?} 0x{:x}", err, err))
Err(anyhow!("FreeType error {:?} 0x{:x}", err, err))
}
}
@ -44,7 +44,7 @@ impl Drop for Face {
impl Face {
/// This is a wrapper around set_char_size and select_size
/// that accounts for some weirdness with eg: color emoji
pub fn set_font_size(&mut self, size: f64, dpi: u32) -> Fallible<(f64, f64)> {
pub fn set_font_size(&mut self, size: f64, dpi: u32) -> anyhow::Result<(f64, f64)> {
log::debug!("set_char_size {} dpi={}", size, dpi);
// Scaling before truncating to integer minimizes the chances of hitting
// the fallback code for set_pixel_sizes below.
@ -93,7 +93,7 @@ impl Face {
char_height: FT_F26Dot6,
horz_resolution: FT_UInt,
vert_resolution: FT_UInt,
) -> Result<(), Error> {
) -> anyhow::Result<()> {
ft_result(
unsafe {
FT_Set_Char_Size(
@ -109,15 +109,15 @@ impl Face {
}
#[allow(unused)]
pub fn set_pixel_sizes(&mut self, char_width: u32, char_height: u32) -> Fallible<()> {
pub fn set_pixel_sizes(&mut self, char_width: u32, char_height: u32) -> anyhow::Result<()> {
ft_result(
unsafe { FT_Set_Pixel_Sizes(self.face, char_width, char_height) },
(),
)
.map_err(|e| e.context("set_pixel_sizes").into())
.with_context(|| format!("set_pixel_sizes {}x{}", char_width, char_height))
}
pub fn select_size(&mut self, idx: usize) -> Result<(), Error> {
pub fn select_size(&mut self, idx: usize) -> anyhow::Result<()> {
ft_result(unsafe { FT_Select_Size(self.face, idx as i32) }, ())
}
@ -126,7 +126,7 @@ impl Face {
glyph_index: FT_UInt,
load_flags: FT_Int32,
render_mode: FT_Render_Mode,
) -> Result<&FT_GlyphSlotRec_, Error> {
) -> anyhow::Result<&FT_GlyphSlotRec_> {
unsafe {
let res = FT_Load_Glyph(self.face, glyph_index, load_flags);
if succeeded(res) {
@ -177,7 +177,7 @@ impl Drop for Library {
}
impl Library {
pub fn new() -> Result<Library, Error> {
pub fn new() -> anyhow::Result<Library> {
let mut lib = ptr::null_mut();
let res = unsafe { FT_Init_FreeType(&mut lib as *mut _) };
let lib = ft_result(res, lib).context("FT_Init_FreeType")?;
@ -190,7 +190,7 @@ impl Library {
Ok(lib)
}
pub fn face_from_locator(&self, handle: &FontDataHandle) -> Fallible<Face> {
pub fn face_from_locator(&self, handle: &FontDataHandle) -> anyhow::Result<Face> {
match handle {
FontDataHandle::OnDisk { path, index } => {
self.new_face(path.to_str().unwrap(), *index as _)
@ -200,7 +200,7 @@ impl Library {
}
#[allow(dead_code)]
pub fn new_face<P>(&self, path: P, face_index: FT_Long) -> Result<Face, Error>
pub fn new_face<P>(&self, path: P, face_index: FT_Long) -> anyhow::Result<Face>
where
P: AsRef<std::path::Path>,
{
@ -223,19 +223,19 @@ impl Library {
)
};
Ok(Face {
face: ft_result(res, face).map_err(|e| {
e.context(format!(
face: ft_result(res, face).with_context(|| {
format!(
"FT_New_Memory_Face for {} index {}",
path.display(),
face_index
))
)
})?,
_bytes: data,
})
}
#[allow(dead_code)]
pub fn new_face_from_slice(&self, data: &[u8], face_index: FT_Long) -> Result<Face, Error> {
pub fn new_face_from_slice(&self, data: &[u8], face_index: FT_Long) -> anyhow::Result<Face> {
let data = data.to_vec();
let mut face = ptr::null_mut();
@ -250,12 +250,12 @@ impl Library {
};
Ok(Face {
face: ft_result(res, face)
.map_err(|e| e.context(format!("FT_New_Memory_Face for index {}", face_index)))?,
.with_context(|| format!("FT_New_Memory_Face for index {}", face_index))?,
_bytes: data,
})
}
pub fn set_lcd_filter(&mut self, filter: FT_LcdFilter) -> Result<(), Error> {
pub fn set_lcd_filter(&mut self, filter: FT_LcdFilter) -> anyhow::Result<()> {
unsafe { ft_result(FT_Library_SetLcdFilter(self.lib, filter), ()) }
}
}

View File

@ -6,7 +6,7 @@ use freetype;
pub use harfbuzz::*;
use failure::{ensure, Error};
use anyhow::{ensure, Error};
use std::mem;
use std::ptr;
use std::slice;

View File

@ -1,7 +1,6 @@
use crate::config::FontAttributes;
use crate::font::fcwrap;
use crate::font::locator::{FontDataHandle, FontLocator};
use failure::Fallible;
use fcwrap::Pattern as FontPattern;
use std::convert::TryInto;
@ -10,7 +9,10 @@ use std::convert::TryInto;
pub struct FontConfigFontLocator {}
impl FontLocator for FontConfigFontLocator {
fn load_fonts(&self, fonts_selection: &[FontAttributes]) -> Fallible<Vec<FontDataHandle>> {
fn load_fonts(
&self,
fonts_selection: &[FontAttributes],
) -> anyhow::Result<Vec<FontDataHandle>> {
let mut fonts = vec![];
let mut fallback = vec![];

View File

@ -4,7 +4,6 @@ use ::font_kit::family_name::FamilyName;
use ::font_kit::handle::Handle;
use ::font_kit::properties::Properties;
use ::font_kit::source::Source;
use failure::Fallible;
/// A FontLocator implemented using the font loading
/// functions provided by Source's from font-kit crate.
@ -12,7 +11,10 @@ impl<S> FontLocator for S
where
S: Source,
{
fn load_fonts(&self, fonts_selection: &[FontAttributes]) -> Fallible<Vec<FontDataHandle>> {
fn load_fonts(
&self,
fonts_selection: &[FontAttributes],
) -> anyhow::Result<Vec<FontDataHandle>> {
let mut handles = vec![];
for font in fonts_selection {

View File

@ -1,14 +1,16 @@
use crate::config::FontAttributes;
use crate::font::locator::{FontDataHandle, FontLocator};
use ::font_loader::system_fonts;
use failure::Fallible;
/// A FontLocator implemented using the system font loading
/// functions provided by the font-loader crate.
pub struct FontLoaderFontLocator {}
impl FontLocator for FontLoaderFontLocator {
fn load_fonts(&self, fonts_selection: &[FontAttributes]) -> Fallible<Vec<FontDataHandle>> {
fn load_fonts(
&self,
fonts_selection: &[FontAttributes],
) -> anyhow::Result<Vec<FontDataHandle>> {
let mut fonts = Vec::new();
for font_attr in fonts_selection {
let mut font_props = system_fonts::FontPropertyBuilder::new()

View File

@ -1,5 +1,5 @@
use crate::config::FontAttributes;
use failure::{format_err, Error, Fallible};
use anyhow::{anyhow, Error};
use serde_derive::*;
use std::path::PathBuf;
use std::sync::Mutex;
@ -50,7 +50,8 @@ impl std::fmt::Debug for FontDataHandle {
pub trait FontLocator {
/// Given a font selection, return the list of successfully loadable
/// FontDataHandle's that correspond to it
fn load_fonts(&self, fonts_selection: &[FontAttributes]) -> Fallible<Vec<FontDataHandle>>;
fn load_fonts(&self, fonts_selection: &[FontAttributes])
-> anyhow::Result<Vec<FontDataHandle>>;
}
#[derive(Debug, Deserialize, Clone, Copy)]
@ -120,7 +121,7 @@ impl std::str::FromStr for FontLocatorSelection {
"fontconfig" => Ok(Self::FontConfig),
"fontloader" => Ok(Self::FontLoader),
"fontkit" => Ok(Self::FontKit),
_ => Err(format_err!(
_ => Err(anyhow!(
"{} is not a valid FontLocatorSelection variant, possible values are {:?}",
s,
Self::variants()

View File

@ -1,4 +1,4 @@
use failure::{format_err, Error, Fallible};
use anyhow::{anyhow, Error};
mod hbwrap;
use std::cell::RefCell;
@ -38,7 +38,7 @@ impl LoadedFont {
self.metrics
}
pub fn shape(&self, text: &str) -> Fallible<Vec<GlyphInfo>> {
pub fn shape(&self, text: &str) -> anyhow::Result<Vec<GlyphInfo>> {
self.shaper.shape(text, self.font_size, self.dpi)
}
@ -46,11 +46,11 @@ impl LoadedFont {
&self,
glyph_pos: u32,
fallback: FallbackIdx,
) -> Fallible<RasterizedGlyph> {
) -> anyhow::Result<RasterizedGlyph> {
let cell = self
.rasterizers
.get(fallback)
.ok_or_else(|| format_err!("no such fallback index: {}", fallback))?;
.ok_or_else(|| anyhow!("no such fallback index: {}", fallback))?;
let mut opt_raster = cell.borrow_mut();
if opt_raster.is_none() {
let raster =
@ -91,7 +91,7 @@ impl FontConfiguration {
/// Given a text style, load (with caching) the font that best
/// matches according to the fontconfig pattern.
pub fn resolve_font(&self, style: &TextStyle) -> Fallible<Rc<LoadedFont>> {
pub fn resolve_font(&self, style: &TextStyle) -> anyhow::Result<Rc<LoadedFont>> {
let mut fonts = self.fonts.borrow_mut();
let config = configuration();
@ -143,7 +143,7 @@ impl FontConfiguration {
}
/// Returns the baseline font specified in the configuration
pub fn default_font(&self) -> Fallible<Rc<LoadedFont>> {
pub fn default_font(&self) -> anyhow::Result<Rc<LoadedFont>> {
self.resolve_font(&configuration().font)
}

View File

@ -18,7 +18,7 @@ use allsorts::tables::{
HeadTable, HheaTable, HmtxTable, MaxpTable, OffsetTable, OpenTypeFile, OpenTypeFont,
};
use allsorts::tag;
use failure::{format_err, Fallible};
use anyhow::anyhow;
use std::convert::TryInto;
use std::path::{Path, PathBuf};
use termwiz::cell::unicode_column_width;
@ -61,7 +61,7 @@ pub struct Names {
}
impl Names {
fn from_name_table_data(name_table: &[u8]) -> Fallible<Names> {
fn from_name_table_data(name_table: &[u8]) -> anyhow::Result<Names> {
Ok(Names {
full_name: get_name(name_table, 4)?,
unique: get_name(name_table, 3).ok(),
@ -78,7 +78,7 @@ impl ParsedFont {
pub fn load_fonts(
config: &Config,
fonts_selection: &[FontAttributes],
) -> Fallible<Vec<FontDataHandle>> {
) -> anyhow::Result<Vec<FontDataHandle>> {
// First discover the available fonts
let mut font_info = vec![];
for path in &config.font_dirs {
@ -117,7 +117,7 @@ impl ParsedFont {
Ok(handles)
}
pub fn from_locator(handle: &FontDataHandle) -> Fallible<Self> {
pub fn from_locator(handle: &FontDataHandle) -> anyhow::Result<Self> {
let (data, index) = match handle {
FontDataHandle::Memory { data, index } => (data.to_vec(), *index),
FontDataHandle::OnDisk { path, index } => {
@ -143,33 +143,33 @@ impl ParsedFont {
let head = otf
.read_table(&file.scope, tag::HEAD)?
.ok_or_else(|| format_err!("HEAD table missing or broken"))?
.ok_or_else(|| anyhow!("HEAD table missing or broken"))?
.read::<HeadTable>()?;
let cmap = otf
.read_table(&file.scope, tag::CMAP)?
.ok_or_else(|| format_err!("CMAP table missing or broken"))?
.ok_or_else(|| anyhow!("CMAP table missing or broken"))?
.read::<Cmap>()?;
let cmap_subtable: CmapSubtable<'static> =
read_cmap_subtable(&cmap)?.ok_or_else(|| format_err!("CMAP subtable not found"))?;
read_cmap_subtable(&cmap)?.ok_or_else(|| anyhow!("CMAP subtable not found"))?;
let maxp = otf
.read_table(&file.scope, tag::MAXP)?
.ok_or_else(|| format_err!("MAXP table not found"))?
.ok_or_else(|| anyhow!("MAXP table not found"))?
.read::<MaxpTable>()?;
let num_glyphs = maxp.num_glyphs;
let post = otf
.read_table(&file.scope, tag::POST)?
.ok_or_else(|| format_err!("POST table not found"))?
.ok_or_else(|| anyhow!("POST table not found"))?
.read::<PostTable>()?;
let hhea = otf
.read_table(&file.scope, tag::HHEA)?
.ok_or_else(|| format_err!("HHEA table not found"))?
.ok_or_else(|| anyhow!("HHEA table not found"))?
.read::<HheaTable>()?;
let hmtx = otf
.read_table(&file.scope, tag::HMTX)?
.ok_or_else(|| format_err!("HMTX table not found"))?
.ok_or_else(|| anyhow!("HMTX table not found"))?
.read_dep::<HmtxTable>((
usize::from(maxp.num_glyphs),
usize::from(hhea.num_h_metrics),
@ -177,13 +177,13 @@ impl ParsedFont {
let gdef_table: Option<GDEFTable> = otf
.find_table_record(tag::GDEF)
.map(|gdef_record| -> Fallible<GDEFTable> {
.map(|gdef_record| -> anyhow::Result<GDEFTable> {
Ok(gdef_record.read_table(&file.scope)?.read::<GDEFTable>()?)
})
.transpose()?;
let opt_gpos_table = otf
.find_table_record(tag::GPOS)
.map(|gpos_record| -> Fallible<LayoutTable<GPOS>> {
.map(|gpos_record| -> anyhow::Result<LayoutTable<GPOS>> {
Ok(gpos_record
.read_table(&file.scope)?
.read::<LayoutTable<GPOS>>()?)
@ -193,7 +193,7 @@ impl ParsedFont {
let gsub_cache = otf
.find_table_record(tag::GSUB)
.map(|gsub| -> Fallible<LayoutTable<GSUB>> {
.map(|gsub| -> anyhow::Result<LayoutTable<GSUB>> {
Ok(gsub.read_table(&file.scope)?.read::<LayoutTable<GSUB>>()?)
})
.transpose()?
@ -220,10 +220,10 @@ impl ParsedFont {
}
/// Resolve a char to the corresponding glyph in the font
pub fn glyph_index_for_char(&self, c: char) -> Fallible<Option<u16>> {
pub fn glyph_index_for_char(&self, c: char) -> anyhow::Result<Option<u16>> {
self.cmap_subtable
.map_glyph(c as u32)
.map_err(|e| format_err!("Error while looking up glyph {}: {}", c, e))
.map_err(|e| anyhow!("Error while looking up glyph {}: {}", c, e))
}
pub fn get_metrics(&self, point_size: f64, dpi: u32) -> FontMetrics {
@ -290,7 +290,7 @@ impl ParsedFont {
lang: u32,
point_size: f64,
dpi: u32,
) -> Fallible<Vec<MaybeShaped>> {
) -> anyhow::Result<Vec<MaybeShaped>> {
let mut glyphs = vec![];
for c in text.as_ref().chars() {
glyphs.push(RawGlyph {
@ -352,7 +352,7 @@ impl ParsedFont {
for glyph_info in infos.into_iter() {
let mut input_glyph = glyph_iter
.next()
.ok_or_else(|| format_err!("more output infos than input glyphs!"))?;
.ok_or_else(|| anyhow!("more output infos than input glyphs!"))?;
while input_glyph.unicodes != glyph_info.glyph.unicodes {
// Info::init_from_glyphs skipped the input glyph, so let's be
@ -365,15 +365,15 @@ impl ParsedFont {
cluster += text.len();
input_glyph = glyph_iter.next().ok_or_else(|| {
format_err!("more output infos than input glyphs! (loop bottom)")
})?;
input_glyph = glyph_iter
.next()
.ok_or_else(|| anyhow!("more output infos than input glyphs! (loop bottom)"))?;
}
let glyph_index = glyph_info
.glyph
.glyph_index
.ok_or_else(|| format_err!("no mapped glyph_index for {:?}", glyph_info))?;
.ok_or_else(|| anyhow!("no mapped glyph_index for {:?}", glyph_info))?;
let horizontal_advance = i32::from(
self.hmtx
@ -431,7 +431,7 @@ fn collect_font_info(
path: &Path,
index: usize,
infos: &mut Vec<(Names, PathBuf, usize)>,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let names = Names::from_name_table_data(name_table_data)?;
infos.push((names, path.to_path_buf(), index));
Ok(())
@ -461,7 +461,7 @@ fn font_info_matches(attr: &FontAttributes, names: &Names) -> bool {
fn parse_and_collect_font_info(
path: &Path,
font_info: &mut Vec<(Names, PathBuf, usize)>,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let data = std::fs::read(path)?;
let scope = allsorts::binary::read::ReadScope::new(&data);
let file = scope.read::<OpenTypeFile>()?;
@ -470,7 +470,7 @@ fn parse_and_collect_font_info(
OpenTypeFont::Single(ttf) => {
let data = ttf
.read_table(&file.scope, allsorts::tag::NAME)?
.ok_or_else(|| format_err!("name table is not present"))?;
.ok_or_else(|| anyhow!("name table is not present"))?;
collect_font_info(data.data(), path, 0, font_info)?;
}
OpenTypeFont::Collection(ttc) => {
@ -481,7 +481,7 @@ fn parse_and_collect_font_info(
.read::<OffsetTable>()?;
let data = ttf
.read_table(&file.scope, allsorts::tag::NAME)?
.ok_or_else(|| format_err!("name table is not present"))?;
.ok_or_else(|| anyhow!("name table is not present"))?;
collect_font_info(data.data(), path, index, font_info).ok();
}
}
@ -490,14 +490,14 @@ fn parse_and_collect_font_info(
Ok(())
}
fn locate_offset_table<'a>(f: &OpenTypeFile<'a>, idx: usize) -> Fallible<OffsetTable<'a>> {
fn locate_offset_table<'a>(f: &OpenTypeFile<'a>, idx: usize) -> anyhow::Result<OffsetTable<'a>> {
match &f.font {
OpenTypeFont::Single(ttf) => Ok(ttf.clone()),
OpenTypeFont::Collection(ttc) => {
let offset_table_offset = ttc
.offset_tables
.read_item(idx)
.map_err(|e| format_err!("font idx={} is not present in ttc file: {}", idx, e))?;
.map_err(|e| anyhow!("font idx={} is not present in ttc file: {}", idx, e))?;
let ttf = f
.scope
.offset(offset_table_offset as usize)
@ -508,17 +508,17 @@ fn locate_offset_table<'a>(f: &OpenTypeFile<'a>, idx: usize) -> Fallible<OffsetT
}
/// Extract the name table data from a font
fn name_table_data<'a>(otf: &OffsetTable<'a>, scope: &ReadScope<'a>) -> Fallible<&'a [u8]> {
fn name_table_data<'a>(otf: &OffsetTable<'a>, scope: &ReadScope<'a>) -> anyhow::Result<&'a [u8]> {
let data = otf
.read_table(scope, allsorts::tag::NAME)?
.ok_or_else(|| format_err!("name table is not present"))?;
.ok_or_else(|| anyhow!("name table is not present"))?;
Ok(data.data())
}
/// Extract a name from the name table
fn get_name(name_table_data: &[u8], name_id: u16) -> Fallible<String> {
fn get_name(name_table_data: &[u8], name_id: u16) -> anyhow::Result<String> {
let cstr = allsorts::get_name::fontcode_get_name(name_table_data, name_id)?
.ok_or_else(|| format_err!("name_id {} not found", name_id))?;
.ok_or_else(|| anyhow!("name_id {} not found", name_id))?;
cstr.into_string()
.map_err(|e| format_err!("name_id {} is not representable as String: {}", name_id, e))
.map_err(|e| anyhow!("name_id {} is not representable as String: {}", name_id, e))
}

View File

@ -3,7 +3,7 @@ use crate::font::rasterizer::FontRasterizer;
use crate::font::units::*;
use crate::font::{ftwrap, RasterizedGlyph};
use ::freetype::FT_GlyphSlotRec_;
use failure::Fallible;
use anyhow::bail;
use std::cell::RefCell;
use std::mem;
use std::slice;
@ -15,7 +15,12 @@ pub struct FreeTypeRasterizer {
}
impl FontRasterizer for FreeTypeRasterizer {
fn rasterize_glyph(&self, glyph_pos: u32, size: f64, dpi: u32) -> Fallible<RasterizedGlyph> {
fn rasterize_glyph(
&self,
glyph_pos: u32,
size: f64,
dpi: u32,
) -> anyhow::Result<RasterizedGlyph> {
self.face.borrow_mut().set_font_size(size, dpi)?;
let render_mode = //ftwrap::FT_Render_Mode::FT_RENDER_MODE_NORMAL;
@ -47,7 +52,7 @@ impl FontRasterizer for FreeTypeRasterizer {
}
ftwrap::FT_Pixel_Mode::FT_PIXEL_MODE_GRAY => self.rasterize_gray(pitch, ft_glyph, data),
ftwrap::FT_Pixel_Mode::FT_PIXEL_MODE_MONO => self.rasterize_mono(pitch, ft_glyph, data),
mode => failure::bail!("unhandled pixel mode: {:?}", mode),
mode => bail!("unhandled pixel mode: {:?}", mode),
};
Ok(glyph)
}
@ -270,7 +275,7 @@ impl FreeTypeRasterizer {
}
}
pub fn from_locator(handle: &FontDataHandle) -> Fallible<Self> {
pub fn from_locator(handle: &FontDataHandle) -> anyhow::Result<Self> {
log::trace!("Rasterizier wants {:?}", handle);
let lib = ftwrap::Library::new()?;
let face = lib.face_from_locator(handle)?;

View File

@ -1,6 +1,6 @@
use crate::font::locator::FontDataHandle;
use crate::font::units::*;
use failure::{bail, format_err, Error, Fallible};
use anyhow::{anyhow, bail, Error};
use serde_derive::*;
use std::sync::Mutex;
@ -20,7 +20,12 @@ pub struct RasterizedGlyph {
/// Rasterizes the specified glyph index in the associated font
/// and returns the generated bitmap
pub trait FontRasterizer {
fn rasterize_glyph(&self, glyph_pos: u32, size: f64, dpi: u32) -> Fallible<RasterizedGlyph>;
fn rasterize_glyph(
&self,
glyph_pos: u32,
size: f64,
dpi: u32,
) -> anyhow::Result<RasterizedGlyph>;
}
#[derive(Debug, Deserialize, Clone, Copy)]
@ -54,7 +59,10 @@ impl FontRasterizerSelection {
vec!["FreeType", "FontKit"]
}
pub fn new_rasterizer(self, handle: &FontDataHandle) -> Fallible<Box<dyn FontRasterizer>> {
pub fn new_rasterizer(
self,
handle: &FontDataHandle,
) -> anyhow::Result<Box<dyn FontRasterizer>> {
match self {
Self::FreeType => Ok(Box::new(freetype::FreeTypeRasterizer::from_locator(
handle,
@ -70,7 +78,7 @@ impl std::str::FromStr for FontRasterizerSelection {
match s.to_lowercase().as_ref() {
"freetype" => Ok(Self::FreeType),
"fontkit" => Ok(Self::FontKit),
_ => Err(format_err!(
_ => Err(anyhow!(
"{} is not a valid FontRasterizerSelection variant, possible values are {:?}",
s,
Self::variants()

View File

@ -1,14 +1,14 @@
use crate::font::locator::FontDataHandle;
use crate::font::parser::*;
use crate::font::shaper::{FallbackIdx, FontMetrics, FontShaper, GlyphInfo};
use failure::{bail, format_err, Fallible};
use anyhow::{anyhow, bail};
pub struct AllsortsShaper {
fonts: Vec<Option<ParsedFont>>,
}
impl AllsortsShaper {
pub fn new(handles: &[FontDataHandle]) -> Fallible<Self> {
pub fn new(handles: &[FontDataHandle]) -> anyhow::Result<Self> {
let mut fonts = vec![];
let mut success = false;
for handle in handles {
@ -40,7 +40,7 @@ impl AllsortsShaper {
font_size: f64,
dpi: u32,
results: &mut Vec<GlyphInfo>,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let font = match self.fonts.get(font_index) {
Some(Some(font)) => font,
Some(None) => {
@ -65,7 +65,7 @@ impl AllsortsShaper {
}
if alt_text == s {
// We already tried to fallback to this and failed
return Err(format_err!("could not fallback to ? character"));
return Err(anyhow!("could not fallback to ? character"));
}
return self.shape_into(
0,
@ -147,7 +147,7 @@ impl AllsortsShaper {
}
impl FontShaper for AllsortsShaper {
fn shape(&self, text: &str, size: f64, dpi: u32) -> Fallible<Vec<GlyphInfo>> {
fn shape(&self, text: &str, size: f64, dpi: u32) -> anyhow::Result<Vec<GlyphInfo>> {
let mut results = vec![];
let script = allsorts::tag::LATN;
let lang = allsorts::tag::DFLT;
@ -156,7 +156,7 @@ impl FontShaper for AllsortsShaper {
Ok(results)
}
fn metrics(&self, size: f64, dpi: u32) -> Fallible<FontMetrics> {
fn metrics(&self, size: f64, dpi: u32) -> anyhow::Result<FontMetrics> {
for font in &self.fonts {
if let Some(font) = font {
return Ok(font.get_metrics(size, dpi));

View File

@ -3,7 +3,7 @@ use crate::font::hbwrap as harfbuzz;
use crate::font::locator::FontDataHandle;
use crate::font::shaper::{FallbackIdx, FontMetrics, FontShaper, GlyphInfo};
use crate::font::units::*;
use failure::{bail, format_err, Fallible};
use anyhow::{anyhow, bail};
use log::{debug, error};
use std::cell::{RefCell, RefMut};
@ -43,7 +43,7 @@ pub struct HarfbuzzShaper {
}
impl HarfbuzzShaper {
pub fn new(handles: &[FontDataHandle]) -> Fallible<Self> {
pub fn new(handles: &[FontDataHandle]) -> anyhow::Result<Self> {
let lib = ftwrap::Library::new()?;
let handles = handles.to_vec();
let mut fonts = vec![];
@ -57,7 +57,7 @@ impl HarfbuzzShaper {
})
}
fn load_fallback(&self, font_idx: FallbackIdx) -> Fallible<Option<RefMut<FontPair>>> {
fn load_fallback(&self, font_idx: FallbackIdx) -> anyhow::Result<Option<RefMut<FontPair>>> {
if font_idx >= self.handles.len() {
return Ok(None);
}
@ -93,7 +93,7 @@ impl HarfbuzzShaper {
s: &str,
font_size: f64,
dpi: u32,
) -> Fallible<Vec<GlyphInfo>> {
) -> anyhow::Result<Vec<GlyphInfo>> {
let features = vec![
// kerning
harfbuzz::feature_from_string("kern")?,
@ -252,14 +252,14 @@ impl HarfbuzzShaper {
}
impl FontShaper for HarfbuzzShaper {
fn shape(&self, text: &str, size: f64, dpi: u32) -> Fallible<Vec<GlyphInfo>> {
fn shape(&self, text: &str, size: f64, dpi: u32) -> anyhow::Result<Vec<GlyphInfo>> {
self.do_shape(0, text, size, dpi)
}
fn metrics(&self, size: f64, dpi: u32) -> Fallible<FontMetrics> {
fn metrics(&self, size: f64, dpi: u32) -> anyhow::Result<FontMetrics> {
let mut pair = self
.load_fallback(0)?
.ok_or_else(|| format_err!("unable to load first font!?"))?;
.ok_or_else(|| anyhow!("unable to load first font!?"))?;
let (cell_width, cell_height) = pair.face.set_font_size(size, dpi)?;
let y_scale = unsafe { (*(*pair.face.face).size).metrics.y_scale as f64 / 65536.0 };
let metrics = FontMetrics {

View File

@ -1,6 +1,6 @@
use crate::font::locator::FontDataHandle;
use crate::font::units::PixelLength;
use failure::{format_err, Error, Fallible};
use anyhow::{anyhow, Error};
use serde_derive::*;
use std::sync::Mutex;
@ -57,11 +57,11 @@ pub struct FontMetrics {
pub trait FontShaper {
/// Shape text and return a vector of GlyphInfo
fn shape(&self, text: &str, size: f64, dpi: u32) -> Fallible<Vec<GlyphInfo>>;
fn shape(&self, text: &str, size: f64, dpi: u32) -> anyhow::Result<Vec<GlyphInfo>>;
/// Compute the font metrics for the preferred font
/// at the specified size.
fn metrics(&self, size: f64, dpi: u32) -> Fallible<FontMetrics>;
fn metrics(&self, size: f64, dpi: u32) -> anyhow::Result<FontMetrics>;
}
#[derive(Debug, Deserialize, Clone, Copy)]
@ -95,7 +95,7 @@ impl FontShaperSelection {
vec!["Harfbuzz", "AllSorts"]
}
pub fn new_shaper(self, handles: &[FontDataHandle]) -> Fallible<Box<dyn FontShaper>> {
pub fn new_shaper(self, handles: &[FontDataHandle]) -> anyhow::Result<Box<dyn FontShaper>> {
match self {
Self::Harfbuzz => Ok(Box::new(harfbuzz::HarfbuzzShaper::new(handles)?)),
Self::Allsorts => Ok(Box::new(allsorts::AllsortsShaper::new(handles)?)),
@ -109,7 +109,7 @@ impl std::str::FromStr for FontShaperSelection {
match s.to_lowercase().as_ref() {
"harfbuzz" => Ok(Self::Harfbuzz),
"allsorts" => Ok(Self::Allsorts),
_ => Err(format_err!(
_ => Err(anyhow!(
"{} is not a valid FontShaperSelection variant, possible values are {:?}",
s,
Self::variants()

View File

@ -7,7 +7,6 @@ use ::window::glium::backend::Context as GliumContext;
use ::window::glium::texture::SrgbTexture2d;
use ::window::*;
use euclid::num::Zero;
use failure::Fallible;
use std::collections::HashMap;
use std::rc::Rc;
use std::sync::Arc;
@ -72,7 +71,7 @@ impl GlyphCache<SrgbTexture2d> {
backend: &Rc<GliumContext>,
fonts: &Rc<FontConfiguration>,
size: usize,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
let surface = Rc::new(SrgbTexture2d::empty_with_format(
backend,
glium::texture::SrgbFormat::U8U8U8U8,
@ -98,7 +97,7 @@ impl<T: Texture2d> GlyphCache<T> {
&mut self,
info: &GlyphInfo,
style: &TextStyle,
) -> Fallible<Rc<CachedGlyph<T>>> {
) -> anyhow::Result<Rc<CachedGlyph<T>>> {
let key = GlyphKey {
font_idx: info.font_idx,
glyph_pos: info.glyph_pos,
@ -116,7 +115,11 @@ impl<T: Texture2d> GlyphCache<T> {
/// Perform the load and render of a glyph
#[allow(clippy::float_cmp)]
fn load_glyph(&mut self, info: &GlyphInfo, style: &TextStyle) -> Fallible<Rc<CachedGlyph<T>>> {
fn load_glyph(
&mut self,
info: &GlyphInfo,
style: &TextStyle,
) -> anyhow::Result<Rc<CachedGlyph<T>>> {
let metrics;
let glyph;
@ -189,7 +192,7 @@ impl<T: Texture2d> GlyphCache<T> {
Ok(Rc::new(glyph))
}
pub fn cached_image(&mut self, image_data: &Arc<ImageData>) -> Fallible<Sprite<T>> {
pub fn cached_image(&mut self, image_data: &Arc<ImageData>) -> anyhow::Result<Sprite<T>> {
if let Some(sprite) = self.image_cache.get(&image_data.id()) {
return Ok(sprite.clone());
}

View File

@ -5,7 +5,6 @@ use crate::mux::tab::Tab;
use crate::mux::window::WindowId as MuxWindowId;
use crate::mux::Mux;
use ::window::*;
use failure::Fallible;
use promise::{BasicExecutor, Executor, SpawnFunc};
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
@ -32,12 +31,12 @@ pub fn is_opengl_enabled() -> bool {
}
impl GuiFrontEnd {
pub fn try_new_no_opengl() -> Fallible<Rc<dyn FrontEnd>> {
pub fn try_new_no_opengl() -> anyhow::Result<Rc<dyn FrontEnd>> {
USE_OPENGL.store(false, Ordering::Release);
Self::try_new()
}
pub fn try_new() -> Fallible<Rc<dyn FrontEnd>> {
pub fn try_new() -> anyhow::Result<Rc<dyn FrontEnd>> {
#[cfg(all(unix, not(target_os = "macos")))]
{
if !configuration().enable_wayland {
@ -85,7 +84,7 @@ impl FrontEnd for GuiFrontEnd {
Box::new(GuiExecutor {})
}
fn run_forever(&self) -> Fallible<()> {
fn run_forever(&self) -> anyhow::Result<()> {
// We run until we've run out of windows in the Mux.
// When we're running ssh we have a transient window
// or two during authentication and we want to de-bounce
@ -130,7 +129,7 @@ impl FrontEnd for GuiFrontEnd {
fontconfig: &Rc<FontConfiguration>,
tab: &Rc<dyn Tab>,
window_id: MuxWindowId,
) -> Fallible<()> {
) -> anyhow::Result<()> {
termwindow::TermWindow::new_window(&configuration(), fontconfig, tab, window_id)
}
}

View File

@ -7,7 +7,7 @@ use ::window::glium::backend::Context as GliumContext;
use ::window::glium::texture::SrgbTexture2d;
use ::window::glium::{IndexBuffer, VertexBuffer};
use ::window::*;
use failure::Fallible;
use anyhow::{anyhow, bail};
use std::cell::RefCell;
use std::rc::Rc;
@ -23,7 +23,7 @@ impl SoftwareRenderState {
fonts: &Rc<FontConfiguration>,
metrics: &RenderMetrics,
size: usize,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
let glyph_cache = RefCell::new(GlyphCache::new(fonts, size));
let util_sprites = UtilSprites::new(&mut glyph_cache.borrow_mut(), metrics)?;
Ok(Self {
@ -50,7 +50,7 @@ impl OpenGLRenderState {
size: usize,
pixel_width: usize,
pixel_height: usize,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
let glyph_cache = RefCell::new(GlyphCache::new_gl(&context, fonts, size)?);
let util_sprites = UtilSprites::new(&mut *glyph_cache.borrow_mut(), metrics)?;
@ -77,9 +77,8 @@ impl OpenGLRenderState {
};
}
let program = program.ok_or_else(|| {
failure::format_err!("Failed to compile shaders: {}", errors.join("\n"))
})?;
let program =
program.ok_or_else(|| anyhow!("Failed to compile shaders: {}", errors.join("\n")))?;
let (glyph_vertex_buffer, glyph_index_buffer) =
Self::compute_vertices(&context, metrics, pixel_width as f32, pixel_height as f32)?;
@ -99,7 +98,7 @@ impl OpenGLRenderState {
metrics: &RenderMetrics,
pixel_width: usize,
pixel_height: usize,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let (glyph_vertex_buffer, glyph_index_buffer) = Self::compute_vertices(
&self.context,
metrics,
@ -131,7 +130,7 @@ impl OpenGLRenderState {
metrics: &RenderMetrics,
width: f32,
height: f32,
) -> Fallible<(VertexBuffer<Vertex>, IndexBuffer<u32>)> {
) -> anyhow::Result<(VertexBuffer<Vertex>, IndexBuffer<u32>)> {
let cell_width = metrics.cell_size.width as f32;
let cell_height = metrics.cell_size.height as f32;
let mut verts = Vec::new();
@ -209,7 +208,7 @@ impl RenderState {
fonts: &Rc<FontConfiguration>,
metrics: &RenderMetrics,
size: Option<usize>,
) -> Fallible<()> {
) -> anyhow::Result<()> {
match self {
RenderState::Software(software) => {
let size = size.unwrap_or_else(|| software.glyph_cache.borrow().atlas.size());
@ -232,7 +231,7 @@ impl RenderState {
metrics: &RenderMetrics,
pixel_width: usize,
pixel_height: usize,
) -> Fallible<()> {
) -> anyhow::Result<()> {
if let RenderState::GL(gl) = self {
gl.advise_of_window_size_change(metrics, pixel_width, pixel_height)?;
}
@ -243,11 +242,11 @@ impl RenderState {
&self,
info: &GlyphInfo,
style: &TextStyle,
) -> Fallible<Rc<CachedGlyph<ImageTexture>>> {
) -> anyhow::Result<Rc<CachedGlyph<ImageTexture>>> {
if let RenderState::Software(software) = self {
software.glyph_cache.borrow_mut().cached_glyph(info, style)
} else {
failure::bail!("attempted to call cached_software_glyph when in gl mode")
bail!("attempted to call cached_software_glyph when in gl mode")
}
}

View File

@ -15,7 +15,7 @@ use ::window::bitmaps::atlas::{OutOfTextureSpace, SpriteSlice};
use ::window::bitmaps::Texture2d;
use ::window::glium::{uniform, Surface};
use ::window::*;
use failure::Fallible;
use anyhow::{anyhow, bail, ensure};
use portable_pty::PtySize;
use std::any::Any;
use std::ops::Range;
@ -38,11 +38,11 @@ struct ClipboardHelper {
}
impl term::Clipboard for ClipboardHelper {
fn get_contents(&self) -> Fallible<String> {
fn get_contents(&self) -> anyhow::Result<String> {
self.window.get_clipboard().wait()
}
fn set_contents(&self, data: Option<String>) -> Fallible<()> {
fn set_contents(&self, data: Option<String>) -> anyhow::Result<()> {
self.window.set_clipboard(data.unwrap_or_else(String::new));
Ok(())
}
@ -385,7 +385,7 @@ impl TermWindow {
fontconfig: &Rc<FontConfiguration>,
tab: &Rc<dyn Tab>,
mux_window_id: MuxWindowId,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let (physical_rows, physical_cols) = tab.renderer().physical_dimensions();
let render_metrics = RenderMetrics::new(fontconfig);
@ -631,7 +631,7 @@ impl TermWindow {
Key::Code(code)
}
fn recreate_texture_atlas(&mut self, size: Option<usize>) -> Fallible<()> {
fn recreate_texture_atlas(&mut self, size: Option<usize>) -> anyhow::Result<()> {
self.render_state
.recreate_texture_atlas(&self.fonts, &self.render_metrics, size)
}
@ -722,11 +722,11 @@ impl TermWindow {
}
}
fn activate_tab(&mut self, tab_idx: usize) -> Fallible<()> {
fn activate_tab(&mut self, tab_idx: usize) -> anyhow::Result<()> {
let mux = Mux::get().unwrap();
let mut window = mux
.get_window_mut(self.mux_window_id)
.ok_or_else(|| failure::format_err!("no such window"))?;
.ok_or_else(|| anyhow!("no such window"))?;
let max = window.len();
if tab_idx < max {
@ -738,14 +738,14 @@ impl TermWindow {
Ok(())
}
fn activate_tab_relative(&mut self, delta: isize) -> Fallible<()> {
fn activate_tab_relative(&mut self, delta: isize) -> anyhow::Result<()> {
let mux = Mux::get().unwrap();
let window = mux
.get_window(self.mux_window_id)
.ok_or_else(|| failure::format_err!("no such window"))?;
.ok_or_else(|| anyhow!("no such window"))?;
let max = window.len();
failure::ensure!(max > 0, "no more tabs");
ensure!(max > 0, "no more tabs");
let active = window.get_active_idx() as isize;
let tab = active + delta;
@ -754,7 +754,7 @@ impl TermWindow {
self.activate_tab(tab as usize % max)
}
fn spawn_tab(&mut self, domain: &SpawnTabDomain) -> Fallible<TabId> {
fn spawn_tab(&mut self, domain: &SpawnTabDomain) -> anyhow::Result<TabId> {
let rows =
(self.dimensions.pixel_height as usize) / self.render_metrics.cell_size.height as usize;
let cols =
@ -779,17 +779,16 @@ impl TermWindow {
SpawnTabDomain::CurrentTabDomain => {
let tab = match mux.get_active_tab_for_window(self.mux_window_id) {
Some(tab) => tab,
None => failure::bail!("window has no tabs?"),
None => bail!("window has no tabs?"),
};
mux.get_domain(tab.domain_id()).ok_or_else(|| {
failure::format_err!("current tab has unresolvable domain id!?")
})?
mux.get_domain(tab.domain_id())
.ok_or_else(|| anyhow!("current tab has unresolvable domain id!?"))?
}
SpawnTabDomain::Domain(id) => mux.get_domain(*id).ok_or_else(|| {
failure::format_err!("spawn_tab called with unresolvable domain id!?")
})?,
SpawnTabDomain::Domain(id) => mux
.get_domain(*id)
.ok_or_else(|| anyhow!("spawn_tab called with unresolvable domain id!?"))?,
SpawnTabDomain::DomainName(name) => mux.get_domain_by_name(&name).ok_or_else(|| {
failure::format_err!("spawn_tab called with unresolvable domain name {}", name)
anyhow!("spawn_tab called with unresolvable domain name {}", name)
})?,
};
let tab = domain.spawn(size, None, self.mux_window_id)?;
@ -803,7 +802,7 @@ impl TermWindow {
let len = {
let window = mux
.get_window(self.mux_window_id)
.ok_or_else(|| failure::format_err!("no such window!?"))?;
.ok_or_else(|| anyhow!("no such window!?"))?;
window.len()
};
self.activate_tab(len - 1)?;
@ -814,7 +813,7 @@ impl TermWindow {
&mut self,
tab: &Rc<dyn Tab>,
assignment: &KeyAssignment,
) -> Fallible<()> {
) -> anyhow::Result<()> {
use KeyAssignment::*;
match assignment {
SpawnTab(spawn_where) => {
@ -1017,7 +1016,7 @@ impl TermWindow {
self.activate_tab_relative(0).ok();
}
fn paint_tab(&mut self, tab: &Rc<dyn Tab>, ctx: &mut dyn PaintContext) -> Fallible<()> {
fn paint_tab(&mut self, tab: &Rc<dyn Tab>, ctx: &mut dyn PaintContext) -> anyhow::Result<()> {
let palette = tab.palette();
let first_line_offset = if self.show_tab_bar { 1 } else { 0 };
@ -1072,7 +1071,11 @@ impl TermWindow {
Ok(())
}
fn paint_tab_opengl(&mut self, tab: &Rc<dyn Tab>, frame: &mut glium::Frame) -> Fallible<()> {
fn paint_tab_opengl(
&mut self,
tab: &Rc<dyn Tab>,
frame: &mut glium::Frame,
) -> anyhow::Result<()> {
let palette = tab.palette();
let background_color = palette.resolve_bg(term::color::ColorAttribute::Default);
@ -1176,7 +1179,7 @@ impl TermWindow {
cursor: &CursorPosition,
terminal: &dyn Renderable,
palette: &ColorPalette,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let gl_state = self.render_state.opengl();
let (_num_rows, num_cols) = terminal.physical_dimensions();
@ -1186,7 +1189,7 @@ impl TermWindow {
let start_pos = line_idx * per_line;
vb.slice_mut(start_pos..start_pos + per_line)
.ok_or_else(|| {
failure::format_err!(
anyhow!(
"we're confused about the screen size; \
line_idx={} start_pos={} per_line={} num_cols={}",
line_idx,
@ -1423,7 +1426,7 @@ impl TermWindow {
cursor: &CursorPosition,
terminal: &dyn Renderable,
palette: &ColorPalette,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let config = configuration();
let (_num_rows, num_cols) = terminal.physical_dimensions();

View File

@ -1,8 +1,8 @@
use crate::font::FontConfiguration;
use crate::mux::tab::Tab;
use crate::mux::window::WindowId;
use anyhow::{anyhow, Error};
use downcast_rs::{impl_downcast, Downcast};
use failure::{format_err, Error, Fallible};
use lazy_static::lazy_static;
use promise::Executor;
use serde_derive::*;
@ -94,7 +94,7 @@ impl std::str::FromStr for FrontEndSelection {
"null" => Ok(FrontEndSelection::Null),
"software" => Ok(FrontEndSelection::Software),
"opengl" => Ok(FrontEndSelection::OpenGL),
_ => Err(format_err!(
_ => Err(anyhow!(
"{} is not a valid FrontEndSelection variant, possible values are {:?}",
s,
FrontEndSelection::variants()
@ -106,14 +106,14 @@ impl std::str::FromStr for FrontEndSelection {
pub trait FrontEnd: Downcast {
/// Run the event loop. Does not return until there is either a fatal
/// error, or until there are no more windows left to manage.
fn run_forever(&self) -> Result<(), Error>;
fn run_forever(&self) -> anyhow::Result<()>;
fn spawn_new_window(
&self,
fontconfig: &Rc<FontConfiguration>,
tab: &Rc<dyn Tab>,
window_id: WindowId,
) -> Fallible<()>;
) -> anyhow::Result<()>;
fn executor(&self) -> Box<dyn Executor>;
fn low_pri_executor(&self) -> Box<dyn Executor>;

View File

@ -5,7 +5,7 @@ use crate::mux::tab::Tab;
use crate::mux::window::WindowId;
use crate::mux::Mux;
use crate::server::listener::spawn_listener;
use failure::{bail, Error, Fallible};
use anyhow::{bail, Error};
use log::info;
use promise::*;
use std::rc::Rc;
@ -85,7 +85,7 @@ impl FrontEnd for MuxServerFrontEnd {
_fontconfig: &Rc<FontConfiguration>,
_tab: &Rc<dyn Tab>,
_window_id: WindowId,
) -> Fallible<()> {
) -> anyhow::Result<()> {
Ok(())
}
}

View File

@ -1,7 +1,7 @@
use crate::mux::domain::DomainId;
use crate::mux::renderable::Renderable;
use crate::mux::tab::{alloc_tab_id, Tab, TabId};
use failure::Error;
use anyhow::Error;
use portable_pty::{Child, MasterPty, PtySize};
use std::cell::{RefCell, RefMut};
use std::sync::Arc;

View File

@ -1,7 +1,7 @@
// Don't create a new standard console window when launched from the windows GUI.
#![windows_subsystem = "windows"]
use failure::{err_msg, format_err, Error, Fallible};
use anyhow::{anyhow, bail, Context, Error};
use promise::Future;
use std::ffi::OsString;
use std::fs::DirBuilder;
@ -251,7 +251,7 @@ struct ImgCatCommand {
}
impl ImgCatCommand {
fn run(&self) -> Fallible<()> {
fn run(&self) -> anyhow::Result<()> {
let mut f = std::fs::File::open(&self.file_name)?;
let mut data = Vec::new();
f.read_to_end(&mut data)?;
@ -273,7 +273,7 @@ impl ImgCatCommand {
}
}
pub fn create_user_owned_dirs(p: &Path) -> Fallible<()> {
pub fn create_user_owned_dirs(p: &Path) -> anyhow::Result<()> {
let mut builder = DirBuilder::new();
builder.recursive(true);
@ -306,17 +306,17 @@ struct SshParameters {
host_and_port: String,
}
fn username_from_env() -> Fallible<String> {
fn username_from_env() -> anyhow::Result<String> {
#[cfg(unix)]
const USER: &str = "USER";
#[cfg(windows)]
const USER: &str = "USERNAME";
std::env::var(USER).map_err(|e| format_err!("while resolving {} env var: {}", USER, e))
std::env::var(USER).with_context(|| format!("while resolving {} env var", USER))
}
impl SshParameters {
fn parse(host: &str) -> Fallible<Self> {
fn parse(host: &str) -> anyhow::Result<Self> {
let parts: Vec<&str> = host.split('@').collect();
if parts.len() == 2 {
@ -330,12 +330,12 @@ impl SshParameters {
host_and_port: parts[0].to_string(),
})
} else {
failure::bail!("failed to parse ssh parameters from `{}`", host);
bail!("failed to parse ssh parameters from `{}`", host);
}
}
}
fn run_ssh(config: config::ConfigHandle, opts: &SshCommand) -> Fallible<()> {
fn run_ssh(config: config::ConfigHandle, opts: &SshCommand) -> anyhow::Result<()> {
let front_end_selection = opts.front_end.unwrap_or(config.front_end);
let gui = front_end_selection.try_new()?;
@ -400,7 +400,7 @@ fn run_ssh(config: config::ConfigHandle, opts: &SshCommand) -> Fallible<()> {
gui.run_forever()
}
fn run_serial(config: config::ConfigHandle, opts: &SerialCommand) -> Fallible<()> {
fn run_serial(config: config::ConfigHandle, opts: &SerialCommand) -> anyhow::Result<()> {
let fontconfig = Rc::new(FontConfiguration::new());
let mut serial = portable_pty::serial::SerialTty::new(&opts.port);
@ -440,12 +440,12 @@ fn client_domains(config: &config::ConfigHandle) -> Vec<ClientDomainConfig> {
domains
}
fn run_mux_client(config: config::ConfigHandle, opts: &ConnectCommand) -> Fallible<()> {
fn run_mux_client(config: config::ConfigHandle, opts: &ConnectCommand) -> anyhow::Result<()> {
let client_config = client_domains(&config)
.into_iter()
.find(|c| c.name() == opts.domain_name)
.ok_or_else(|| {
format_err!(
anyhow!(
"no multiplexer domain with name `{}` was found in the configuration",
opts.domain_name
)
@ -484,13 +484,13 @@ fn run_mux_client(config: config::ConfigHandle, opts: &ConnectCommand) -> Fallib
gui.run_forever()
}
fn run_terminal_gui(config: config::ConfigHandle, opts: &StartCommand) -> Fallible<()> {
fn run_terminal_gui(config: config::ConfigHandle, opts: &StartCommand) -> anyhow::Result<()> {
#[cfg(unix)]
{
if opts.daemonize {
let stdout = config.daemon_options.open_stdout()?;
let stderr = config.daemon_options.open_stderr()?;
let home_dir = dirs::home_dir().ok_or_else(|| err_msg("can't find home dir"))?;
let home_dir = dirs::home_dir().ok_or_else(|| anyhow!("can't find home dir"))?;
let mut daemonize = daemonize::Daemonize::new()
.stdout(stdout)
.stderr(stderr)
@ -511,10 +511,10 @@ fn run_terminal_gui(config: config::ConfigHandle, opts: &StartCommand) -> Fallib
| DaemonizeError::LockPidfile(_)
| DaemonizeError::ChownPidfile(_)
| DaemonizeError::WritePid => {
failure::bail!("{} {}", err, config.daemon_options.pid_file().display());
anyhow!("{} {}", err, config.daemon_options.pid_file().display());
}
DaemonizeError::ChangeDirectory => {
failure::bail!("{} {}", err, home_dir.display());
anyhow!("{} {}", err, home_dir.display());
}
_ => return Err(err.into()),
}
@ -541,15 +541,15 @@ fn run_terminal_gui(config: config::ConfigHandle, opts: &StartCommand) -> Fallib
None
};
let domain: Arc<dyn Domain> = Arc::new(LocalDomain::new("local")?);
let domain: Arc<dyn Domain> = Arc::new(LocalDomain::new("local").map_err(Error::msg)?);
let mux = Rc::new(mux::Mux::new(Some(domain.clone())));
Mux::set_mux(&mux);
let front_end = opts.front_end.unwrap_or(config.front_end);
let gui = front_end.try_new()?;
let gui = front_end.try_new().map_err(Error::msg)?;
domain.attach()?;
fn record_domain(mux: &Rc<Mux>, client: ClientDomain) -> Fallible<Arc<dyn Domain>> {
fn record_domain(mux: &Rc<Mux>, client: ClientDomain) -> anyhow::Result<Arc<dyn Domain>> {
let domain: Arc<dyn Domain> = Arc::new(client);
mux.add_domain(&domain);
Ok(domain)
@ -587,7 +587,7 @@ fn main() {
}
}
fn run() -> Result<(), Error> {
fn run() -> anyhow::Result<()> {
// This is a bit gross.
// In order to not to automatically open a standard windows console when
// we run, we use the windows_subsystem attribute at the top of this
@ -616,7 +616,7 @@ fn run() -> Result<(), Error> {
*/
std::env::set_current_dir(
dirs::home_dir().ok_or_else(|| err_msg("can't find home dir"))?,
dirs::home_dir().ok_or_else(|| anyhow!("can't find home dir"))?,
)?;
}
};
@ -626,7 +626,7 @@ fn run() -> Result<(), Error> {
if !opts.skip_config {
config::reload();
}
let config = config::configuration_result()?;
let config = config::configuration_result().map_err(Error::msg)?;
match opts
.cmd
@ -638,13 +638,13 @@ fn run() -> Result<(), Error> {
log::info!("Using configuration: {:#?}\nopts: {:#?}", config, opts);
run_terminal_gui(config, &start)
}
SubCommand::Ssh(ssh) => run_ssh(config, &ssh),
SubCommand::Serial(serial) => run_serial(config, &serial),
SubCommand::Connect(connect) => run_mux_client(config, &connect),
SubCommand::ImageCat(cmd) => cmd.run(),
SubCommand::Ssh(ssh) => run_ssh(config, &ssh).map_err(Error::msg),
SubCommand::Serial(serial) => run_serial(config, &serial).map_err(Error::msg),
SubCommand::Connect(connect) => run_mux_client(config, &connect).map_err(Error::msg),
SubCommand::ImageCat(cmd) => cmd.run().map_err(Error::msg),
SubCommand::Cli(cli) => {
let initial = true;
let client = Client::new_default_unix_domain(initial)?;
let client = Client::new_default_unix_domain(initial).map_err(Error::msg)?;
match cli.sub {
CliSubCommand::List => {
let cols = vec![
@ -666,7 +666,7 @@ fn run() -> Result<(), Error> {
},
];
let mut data = vec![];
let tabs = client.list_tabs().wait()?;
let tabs = client.list_tabs().wait().map_err(Error::msg)?;
for entry in tabs.tabs.iter() {
data.push(vec![
entry.window_id.to_string(),
@ -697,7 +697,7 @@ fn run() -> Result<(), Error> {
// and pull data from stdin and write it to the socket
let stdin = std::io::stdin();
consume_stream(stdin.lock(), stream)?;
consume_stream(stdin.lock(), stream).map_err(Error::msg)?;
}
}
Ok(())
@ -705,7 +705,7 @@ fn run() -> Result<(), Error> {
}
}
fn consume_stream<F: Read, T: Write>(mut from_stream: F, mut to_stream: T) -> Fallible<()> {
fn consume_stream<F: Read, T: Write>(mut from_stream: F, mut to_stream: T) -> anyhow::Result<()> {
let mut buf = [0u8; 8192];
loop {

View File

@ -10,8 +10,8 @@ use crate::localtab::LocalTab;
use crate::mux::tab::Tab;
use crate::mux::window::WindowId;
use crate::mux::Mux;
use anyhow::{bail, Error};
use downcast_rs::{impl_downcast, Downcast};
use failure::{Error, Fallible};
use log::info;
use portable_pty::cmdbuilder::CommandBuilder;
use portable_pty::{PtySize, PtySystem};
@ -47,10 +47,10 @@ pub trait Domain: Downcast {
fn domain_name(&self) -> &str;
/// Re-attach to any tabs that might be pre-existing in this domain
fn attach(&self) -> Fallible<()>;
fn attach(&self) -> anyhow::Result<()>;
/// Detach all tabs
fn detach(&self) -> Fallible<()>;
fn detach(&self) -> anyhow::Result<()>;
/// Indicates the state of the domain
fn state(&self) -> DomainState;
@ -125,12 +125,12 @@ impl Domain for LocalDomain {
&self.name
}
fn attach(&self) -> Fallible<()> {
fn attach(&self) -> anyhow::Result<()> {
Ok(())
}
fn detach(&self) -> Fallible<()> {
failure::bail!("detach not implemented");
fn detach(&self) -> anyhow::Result<()> {
bail!("detach not implemented");
}
fn state(&self) -> DomainState {

View File

@ -3,9 +3,8 @@ use crate::mux::tab::{Tab, TabId};
use crate::mux::window::{Window, WindowId};
use crate::ratelim::RateLimiter;
use crate::server::pollable::{pollable_channel, PollableReceiver, PollableSender};
use anyhow::{anyhow, Error};
use domain::{Domain, DomainId};
use failure::{format_err, Error, Fallible};
use failure_derive::*;
use log::{debug, error};
use portable_pty::ExitStatus;
use promise::Future;
@ -18,6 +17,7 @@ use std::sync::Arc;
use std::thread;
use term::TerminalHost;
use termwiz::hyperlink::Hyperlink;
use thiserror::*;
pub mod domain;
pub mod renderable;
@ -148,7 +148,7 @@ impl Mux {
}
}
pub fn subscribe(&self) -> Fallible<MuxSubscriber> {
pub fn subscribe(&self) -> anyhow::Result<MuxSubscriber> {
let sub_id = SUB_ID.fetch_add(1, Ordering::Relaxed);
let (tx, rx) = pollable_channel()?;
self.subscribers.borrow_mut().insert(sub_id, tx);
@ -286,10 +286,10 @@ impl Mux {
window_id
}
pub fn add_tab_to_window(&self, tab: &Rc<dyn Tab>, window_id: WindowId) -> Fallible<()> {
pub fn add_tab_to_window(&self, tab: &Rc<dyn Tab>, window_id: WindowId) -> anyhow::Result<()> {
let mut window = self
.get_window_mut(window_id)
.ok_or_else(|| format_err!("add_tab_to_window: no such window_id {}", window_id))?;
.ok_or_else(|| anyhow!("add_tab_to_window: no such window_id {}", window_id))?;
window.push(tab);
Ok(())
}
@ -324,13 +324,13 @@ impl Mux {
}
}
#[derive(Debug, Fail)]
#[derive(Debug, Error)]
#[allow(dead_code)]
pub enum SessionTerminated {
#[fail(display = "Process exited: {:?}", status)]
#[error("Process exited: {:?}", status)]
ProcessStatus { status: ExitStatus },
#[fail(display = "Error: {:?}", err)]
#[error("Error: {:?}", err)]
Error { err: Error },
#[fail(display = "Window Closed")]
#[error("Window Closed")]
WindowClosed,
}

View File

@ -3,7 +3,6 @@ use crate::mux::domain::DomainId;
use crate::mux::renderable::Renderable;
use crate::mux::Mux;
use downcast_rs::{impl_downcast, Downcast};
use failure::Fallible;
use portable_pty::PtySize;
use std::cell::RefMut;
use std::sync::{Arc, Mutex};
@ -52,12 +51,12 @@ pub trait Tab: Downcast {
fn tab_id(&self) -> TabId;
fn renderer(&self) -> RefMut<dyn Renderable>;
fn get_title(&self) -> String;
fn send_paste(&self, text: &str) -> Fallible<()>;
fn reader(&self) -> Fallible<Box<dyn std::io::Read + Send>>;
fn send_paste(&self, text: &str) -> anyhow::Result<()>;
fn reader(&self) -> anyhow::Result<Box<dyn std::io::Read + Send>>;
fn writer(&self) -> RefMut<dyn std::io::Write>;
fn resize(&self, size: PtySize) -> Fallible<()>;
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> Fallible<()>;
fn mouse_event(&self, event: MouseEvent, host: &mut dyn TerminalHost) -> Fallible<()>;
fn resize(&self, size: PtySize) -> anyhow::Result<()>;
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()>;
fn mouse_event(&self, event: MouseEvent, host: &mut dyn TerminalHost) -> anyhow::Result<()>;
fn advance_bytes(&self, buf: &[u8], host: &mut dyn TerminalHost);
fn is_dead(&self) -> bool;
fn palette(&self) -> ColorPalette;
@ -71,7 +70,7 @@ pub trait Tab: Downcast {
fn selection_range(&self) -> Option<SelectionRange>;
fn selection_text(&self) -> Option<String>;
fn trickle_paste(&self, text: String) -> Fallible<()> {
fn trickle_paste(&self, text: String) -> anyhow::Result<()> {
if text.len() <= PASTE_CHUNK_SIZE {
// Send it all now
self.send_paste(&text)?;

View File

@ -9,8 +9,8 @@ use crate::server::pollable::*;
use crate::server::tab::ClientTab;
use crate::server::UnixStream;
use crate::ssh::ssh_connect;
use anyhow::{anyhow, bail, Context, Error};
use crossbeam_channel::TryRecvError;
use failure::{bail, err_msg, format_err, Fallible};
use filedescriptor::{pollfd, AsRawSocketDescriptor};
use log::info;
use promise::{Future, Promise};
@ -61,28 +61,26 @@ macro_rules! rpc {
};
}
fn process_unilateral(local_domain_id: DomainId, decoded: DecodedPdu) -> Fallible<()> {
fn process_unilateral(local_domain_id: DomainId, decoded: DecodedPdu) -> anyhow::Result<()> {
if let Some(tab_id) = decoded.pdu.tab_id() {
let pdu = decoded.pdu;
Future::with_executor(executor(), move || {
let mux = Mux::get().unwrap();
let client_domain = mux
.get_domain(local_domain_id)
.ok_or_else(|| format_err!("no such domain {}", local_domain_id))?;
.ok_or_else(|| anyhow!("no such domain {}", local_domain_id))?;
let client_domain = client_domain
.downcast_ref::<ClientDomain>()
.ok_or_else(|| {
format_err!("domain {} is not a ClientDomain instance", local_domain_id)
anyhow!("domain {} is not a ClientDomain instance", local_domain_id)
})?;
let local_tab_id = client_domain
.remote_to_local_tab_id(tab_id)
.ok_or_else(|| {
format_err!("remote tab id {} does not have a local tab id", tab_id)
})?;
.ok_or_else(|| anyhow!("remote tab id {} does not have a local tab id", tab_id))?;
let tab = mux
.get_tab(local_tab_id)
.ok_or_else(|| format_err!("no such tab {}", local_tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", local_tab_id))?;
let client_tab = tab.downcast_ref::<ClientTab>().ok_or_else(|| {
log::error!(
"received unilateral PDU for tab {} which is \
@ -90,7 +88,7 @@ fn process_unilateral(local_domain_id: DomainId, decoded: DecodedPdu) -> Fallibl
local_tab_id,
pdu
);
format_err!(
anyhow!(
"received unilateral PDU for tab {} which is \
not an instance of ClientTab: {:?}",
local_tab_id,
@ -109,7 +107,7 @@ fn client_thread(
reconnectable: &mut Reconnectable,
local_domain_id: DomainId,
rx: &mut PollableReceiver<ReaderMessage>,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let mut next_serial = 1u64;
let mut promises = HashMap::new();
let mut read_buffer = Vec::with_capacity(1024);
@ -255,7 +253,7 @@ impl Write for SshStream {
}
impl ReadAndWrite for SshStream {
fn set_non_blocking(&self, non_blocking: bool) -> Fallible<()> {
fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()> {
self.sess.set_blocking(!non_blocking);
Ok(())
}
@ -294,7 +292,7 @@ impl Reconnectable {
}
}
fn connect(&mut self, initial: bool) -> Fallible<()> {
fn connect(&mut self, initial: bool) -> anyhow::Result<()> {
match self.config.clone() {
ClientDomainConfig::Unix(unix_dom) => self.unix_connect(unix_dom, initial),
ClientDomainConfig::Tls(tls) => self.tls_connect(tls),
@ -302,7 +300,7 @@ impl Reconnectable {
}
}
fn ssh_connect(&mut self, ssh_dom: SshDomain, initial: bool) -> Fallible<()> {
fn ssh_connect(&mut self, ssh_dom: SshDomain, initial: bool) -> anyhow::Result<()> {
let sess = ssh_connect(&ssh_dom.remote_address, &ssh_dom.username)?;
let mut chan = sess.channel_session()?;
@ -319,7 +317,7 @@ impl Reconnectable {
Ok(())
}
fn unix_connect(&mut self, unix_dom: UnixDomain, initial: bool) -> Fallible<()> {
fn unix_connect(&mut self, unix_dom: UnixDomain, initial: bool) -> anyhow::Result<()> {
let sock_path = unix_dom.socket_path();
info!("connect to {}", sock_path.display());
@ -364,9 +362,8 @@ impl Reconnectable {
// wezterm is terminated, but it otherwise invisible.
std::mem::forget(pair.master);
unix_connect_with_retry(&sock_path).map_err(|e| {
format_err!("failed to connect to {}: {}", sock_path.display(), e)
})?
unix_connect_with_retry(&sock_path)
.with_context(|| format!("failed to connect to {}", sock_path.display()))?
}
};
@ -376,7 +373,7 @@ impl Reconnectable {
}
#[cfg(any(feature = "openssl", unix))]
pub fn tls_connect(&mut self, tls_client: TlsDomainClient) -> Fallible<()> {
pub fn tls_connect(&mut self, tls_client: TlsDomainClient) -> anyhow::Result<()> {
use crate::server::listener::read_bytes;
use openssl::ssl::{SslConnector, SslFiletype, SslMethod};
use openssl::x509::X509;
@ -386,7 +383,7 @@ impl Reconnectable {
let remote_address = &tls_client.remote_address;
let remote_host_name = remote_address.split(':').next().ok_or_else(|| {
format_err!(
anyhow!(
"expected mux_server_remote_address to have the form 'host:port', but have {}",
remote_address
)
@ -403,7 +400,7 @@ impl Reconnectable {
if let Some(key_file) = tls_client.pem_private_key.as_ref() {
connector.set_private_key_file(key_file, SslFiletype::PEM)?;
}
fn load_cert(name: &Path) -> Fallible<X509> {
fn load_cert(name: &Path) -> anyhow::Result<X509> {
let cert_bytes = read_bytes(name)?;
log::trace!("loaded {}", name.display());
Ok(X509::from_pem(&cert_bytes)?)
@ -426,7 +423,7 @@ impl Reconnectable {
.verify_hostname(!tls_client.accept_invalid_hostnames);
let stream = TcpStream::connect(remote_address)
.map_err(|e| format_err!("connecting to {}: {}", remote_address, e))?;
.with_context(|| format!("connecting to {}", remote_address))?;
stream.set_nodelay(true)?;
let stream = Box::new(
@ -439,13 +436,10 @@ impl Reconnectable {
.unwrap_or(remote_host_name),
stream,
)
.map_err(|e| {
format_err!(
"SslConnector for {} with host name {}: {} ({:?})",
remote_address,
remote_host_name,
e,
e
.with_context(|| {
format!(
"SslConnector for {} with host name {}",
remote_address, remote_host_name,
)
})?,
);
@ -454,7 +448,7 @@ impl Reconnectable {
}
#[cfg(not(any(feature = "openssl", unix)))]
pub fn tls_connect(&mut self, tls_client: TlsDomainClient) -> Fallible<()> {
pub fn tls_connect(&mut self, tls_client: TlsDomainClient) -> anyhow::Result<()> {
use crate::server::listener::IdentitySource;
use native_tls::TlsConnector;
use std::convert::TryInto;
@ -462,7 +456,7 @@ impl Reconnectable {
let remote_address = &tls_client.remote_address;
let remote_host_name = remote_address.split(':').next().ok_or_else(|| {
format_err!(
anyhow!(
"expected mux_server_remote_address to have the form 'host:port', but have {}",
remote_address
)
@ -472,7 +466,7 @@ impl Reconnectable {
key: tls_client
.pem_private_key
.as_ref()
.ok_or_else(|| failure::err_msg("missing pem_private_key config value"))?
.ok_or_else(|| anyhow!("missing pem_private_key config value"))?
.into(),
cert: tls_client.pem_cert.clone(),
chain: tls_client.pem_ca.clone(),
@ -484,18 +478,19 @@ impl Reconnectable {
.build()?;
let stream = TcpStream::connect(remote_address)
.map_err(|e| format_err!("connecting to {}: {}", remote_address, e))?;
.with_context(|| format!("connecting to {}", remote_address))?;
stream.set_nodelay(true)?;
let stream = Box::new(connector.connect(remote_host_name, stream).map_err(|e| {
format_err!(
"TlsConnector for {} with host name {}: {} ({:?})",
remote_address,
remote_host_name,
e,
e
)
})?);
let stream = Box::new(
connector
.connect(remote_host_name, stream)
.with_context(|| {
format!(
"TlsConnector for {} with host name {}",
remote_address, remote_host_name,
)
})?,
);
self.stream.replace(stream);
Ok(())
}
@ -543,12 +538,12 @@ impl Client {
let mux = Mux::get().unwrap();
let client_domain = mux
.get_domain(local_domain_id)
.ok_or_else(|| format_err!("no such domain {}", local_domain_id))?;
.ok_or_else(|| anyhow!("no such domain {}", local_domain_id))?;
let client_domain =
client_domain
.downcast_ref::<ClientDomain>()
.ok_or_else(|| {
format_err!("domain {} is not a ClientDomain instance", local_domain_id)
anyhow!("domain {} is not a ClientDomain instance", local_domain_id)
})?;
client_domain.perform_detach();
Ok(())
@ -566,12 +561,12 @@ impl Client {
self.local_domain_id
}
pub fn new_default_unix_domain(initial: bool) -> Fallible<Self> {
pub fn new_default_unix_domain(initial: bool) -> anyhow::Result<Self> {
let config = configuration();
let unix_dom = config
.unix_domains
.first()
.ok_or_else(|| err_msg("no default unix domain is configured"))?;
.ok_or_else(|| anyhow!("no default unix domain is configured"))?;
Self::new_unix_domain(alloc_domain_id(), unix_dom, initial)
}
@ -579,21 +574,24 @@ impl Client {
local_domain_id: DomainId,
unix_dom: &UnixDomain,
initial: bool,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
let mut reconnectable =
Reconnectable::new(ClientDomainConfig::Unix(unix_dom.clone()), None);
reconnectable.connect(initial)?;
Ok(Self::new(local_domain_id, reconnectable))
}
pub fn new_tls(local_domain_id: DomainId, tls_client: &TlsDomainClient) -> Fallible<Self> {
pub fn new_tls(
local_domain_id: DomainId,
tls_client: &TlsDomainClient,
) -> anyhow::Result<Self> {
let mut reconnectable =
Reconnectable::new(ClientDomainConfig::Tls(tls_client.clone()), None);
reconnectable.connect(true)?;
Ok(Self::new(local_domain_id, reconnectable))
}
pub fn new_ssh(local_domain_id: DomainId, ssh_dom: &SshDomain) -> Fallible<Self> {
pub fn new_ssh(local_domain_id: DomainId, ssh_dom: &SshDomain) -> anyhow::Result<Self> {
let mut reconnectable = Reconnectable::new(ClientDomainConfig::Ssh(ssh_dom.clone()), None);
reconnectable.connect(true)?;
Ok(Self::new(local_domain_id, reconnectable))
@ -604,7 +602,7 @@ impl Client {
let future = promise.get_future().expect("future already taken!?");
match self.sender.send(ReaderMessage::SendPdu { pdu, promise }) {
Ok(_) => future,
Err(err) => Future::err(format_err!("{}", err)),
Err(err) => Future::err(Error::msg(err)),
}
}

View File

@ -13,7 +13,7 @@
use crate::mux::domain::DomainId;
use crate::mux::tab::TabId;
use crate::mux::window::WindowId;
use failure::{bail, Error, Fallible};
use anyhow::{bail, Error};
use leb128;
use log::debug;
use portable_pty::{CommandBuilder, PtySize};
@ -236,7 +236,7 @@ pdu! {
}
impl Pdu {
pub fn stream_decode(buffer: &mut Vec<u8>) -> Fallible<Option<DecodedPdu>> {
pub fn stream_decode(buffer: &mut Vec<u8>) -> anyhow::Result<Option<DecodedPdu>> {
let mut cursor = Cursor::new(buffer.as_slice());
match Self::decode(&mut cursor) {
Ok(decoded) => {
@ -272,7 +272,7 @@ impl Pdu {
pub fn try_read_and_decode<R: std::io::Read>(
r: &mut R,
buffer: &mut Vec<u8>,
) -> Fallible<Option<DecodedPdu>> {
) -> anyhow::Result<Option<DecodedPdu>> {
loop {
if let Some(decoded) = Self::stream_decode(buffer)? {
return Ok(Some(decoded));

View File

@ -8,7 +8,7 @@ use crate::mux::Mux;
use crate::server::client::Client;
use crate::server::codec::Spawn;
use crate::server::tab::ClientTab;
use failure::{err_msg, Fallible};
use anyhow::{anyhow, bail};
use portable_pty::{CommandBuilder, PtySize};
use std::cell::RefCell;
use std::collections::HashMap;
@ -160,10 +160,10 @@ impl Domain for ClientDomain {
size: PtySize,
command: Option<CommandBuilder>,
window: WindowId,
) -> Fallible<Rc<dyn Tab>> {
) -> anyhow::Result<Rc<dyn Tab>> {
let inner = self
.inner()
.ok_or_else(|| err_msg("domain is not attached"))?;
.ok_or_else(|| anyhow!("domain is not attached"))?;
let remote_tab_id = {
let result = inner
.client
@ -187,7 +187,7 @@ impl Domain for ClientDomain {
Ok(tab)
}
fn attach(&self) -> Fallible<()> {
fn attach(&self) -> anyhow::Result<()> {
let mux = Mux::get().unwrap();
let client = match &self.config {
ClientDomainConfig::Unix(unix) => {
@ -237,8 +237,8 @@ impl Domain for ClientDomain {
Ok(())
}
fn detach(&self) -> Fallible<()> {
failure::bail!("detach not implemented");
fn detach(&self) -> anyhow::Result<()> {
bail!("detach not implemented");
}
fn state(&self) -> DomainState {

View File

@ -7,8 +7,8 @@ use crate::ratelim::RateLimiter;
use crate::server::codec::*;
use crate::server::pollable::*;
use crate::server::UnixListener;
use anyhow::{anyhow, bail, Context, Error};
use crossbeam_channel::TryRecvError;
use failure::{bail, err_msg, format_err, Error, Fallible};
#[cfg(unix)]
use libc::{mode_t, umask};
use log::{debug, error};
@ -69,10 +69,10 @@ pub enum IdentitySource {
},
}
pub fn read_bytes<T: AsRef<Path>>(path: T) -> Fallible<Vec<u8>> {
pub fn read_bytes<T: AsRef<Path>>(path: T) -> anyhow::Result<Vec<u8>> {
let path = path.as_ref();
let mut f = std::fs::File::open(path)
.map_err(|e| format_err!("opening file {}: {}", path.display(), e))?;
let mut f =
std::fs::File::open(path).with_context(|| format!("opening file {}", path.display()))?;
let mut buf = Vec::new();
f.read_to_end(&mut buf)?;
Ok(buf)
@ -83,7 +83,7 @@ fn pem_files_to_identity(
key: PathBuf,
cert: Option<PathBuf>,
chain: Option<PathBuf>,
) -> Fallible<Identity> {
) -> anyhow::Result<Identity> {
// This is a bit of a redundant dance around;
// the native_tls interface only allows for pkcs12
// encoded identity information, but in my use case
@ -113,14 +113,13 @@ fn pem_files_to_identity(
let pkcs12 = builder.build(password, "", &pkey, &x509_cert)?;
let der = pkcs12.to_der()?;
Identity::from_pkcs12(&der, password).map_err(|e| {
format_err!(
Identity::from_pkcs12(&der, password).with_context(|| {
format!(
"error creating identity from pkcs12 generated \
from PemFiles {}, {:?}, {:?}: {}",
from PemFiles {}, {:?}, {:?}",
key.display(),
cert,
chain,
e
)
})
}
@ -130,20 +129,19 @@ fn pem_files_to_identity(
_key: PathBuf,
_cert: Option<PathBuf>,
_chain: Option<PathBuf>,
) -> Fallible<Identity> {
) -> anyhow::Result<Identity> {
bail!("recompile wezterm using --features openssl")
}
impl TryFrom<IdentitySource> for Identity {
type Error = Error;
fn try_from(source: IdentitySource) -> Fallible<Identity> {
fn try_from(source: IdentitySource) -> anyhow::Result<Identity> {
match source {
IdentitySource::Pkcs12File { path, password } => {
let bytes = read_bytes(&path)?;
Identity::from_pkcs12(&bytes, &password).map_err(|e| {
format_err!("error loading pkcs12 file '{}': {}", path.display(), e)
})
Identity::from_pkcs12(&bytes, &password)
.with_context(|| format!("error loading pkcs12 file '{}'", path.display()))
}
IdentitySource::PemFiles { key, cert, chain } => {
pem_files_to_identity(key, cert, chain)
@ -200,24 +198,20 @@ mod not_ossl {
}
}
pub fn spawn_tls_listener(tls_server: &TlsDomainServer) -> Fallible<()> {
pub fn spawn_tls_listener(tls_server: &TlsDomainServer) -> anyhow::Result<()> {
let identity = IdentitySource::PemFiles {
key: tls_server
.pem_private_key
.as_ref()
.ok_or_else(|| err_msg("missing pem_private_key config value"))?
.ok_or_else(|| anyhow!("missing pem_private_key config value"))?
.into(),
cert: tls_server.pem_cert.clone(),
chain: tls_server.pem_ca.clone(),
};
let mut net_listener = NetListener::new(
TcpListener::bind(&tls_server.bind_address).map_err(|e| {
format_err!(
"error binding to bind_address {}: {}",
tls_server.bind_address,
e
)
TcpListener::bind(&tls_server.bind_address).with_context(|| {
format!("error binding to bind_address {}", tls_server.bind_address,)
})?,
TlsAcceptor::new(identity.try_into()?)?,
);
@ -256,16 +250,16 @@ mod ossl {
/// user running this mux server instance, or must match
/// a special encoded prefix set up by a proprietary PKI
/// infrastructure in an environment used by the author.
fn verify_peer_cert<T>(stream: &SslStream<T>) -> Fallible<()> {
fn verify_peer_cert<T>(stream: &SslStream<T>) -> anyhow::Result<()> {
let cert = stream
.ssl()
.peer_certificate()
.ok_or_else(|| err_msg("no peer cert"))?;
.ok_or_else(|| anyhow!("no peer cert"))?;
let subject = cert.subject_name();
let cn = subject
.entries_by_nid(openssl::nid::Nid::COMMONNAME)
.next()
.ok_or_else(|| err_msg("cert has no CN"))?;
.ok_or_else(|| anyhow!("cert has no CN"))?;
let cn_str = cn.data().as_utf8()?.to_string();
let wanted_unix_name = std::env::var("USER")?;
@ -342,7 +336,7 @@ mod ossl {
if let Some(key_file) = tls_server.pem_private_key.as_ref() {
acceptor.set_private_key_file(key_file, SslFiletype::PEM)?;
}
fn load_cert(name: &Path) -> Fallible<X509> {
fn load_cert(name: &Path) -> anyhow::Result<X509> {
let cert_bytes = read_bytes(name)?;
log::trace!("loaded {}", name.display());
Ok(X509::from_pem(&cert_bytes)?)
@ -364,11 +358,10 @@ mod ossl {
let acceptor = acceptor.build();
let mut net_listener = OpenSSLNetListener::new(
TcpListener::bind(&tls_server.bind_address).map_err(|e| {
format_err!(
"error binding to mux_server_bind_address {}: {}",
TcpListener::bind(&tls_server.bind_address).with_context(|| {
format!(
"error binding to mux_server_bind_address {}",
tls_server.bind_address,
e
)
})?,
acceptor,
@ -392,7 +385,7 @@ fn maybe_push_tab_changes(
surfaces: &Arc<Mutex<HashMap<TabId, ClientSurfaceState>>>,
tab: &Rc<dyn Tab>,
sender: PollableSender<DecodedPdu>,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let tab_id = tab.tab_id();
let mut surfaces = surfaces.lock().unwrap();
let (rows, cols) = tab.renderer().physical_dimensions();
@ -507,11 +500,11 @@ struct RemoteClipboard {
}
impl Clipboard for RemoteClipboard {
fn get_contents(&self) -> Fallible<String> {
fn get_contents(&self) -> anyhow::Result<String> {
Ok("".to_owned())
}
fn set_contents(&self, clipboard: Option<String>) -> Fallible<()> {
fn set_contents(&self, clipboard: Option<String>) -> anyhow::Result<()> {
self.sender.send(DecodedPdu {
serial: 0,
pdu: Pdu::SetClipboard(SetClipboard {
@ -606,7 +599,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
maybe_push_tab_changes(&surfaces, &tab, sender)?;
Ok(())
});
@ -635,7 +628,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
}
}
fn process_one(&mut self, decoded: DecodedPdu) -> Fallible<()> {
fn process_one(&mut self, decoded: DecodedPdu) -> anyhow::Result<()> {
let start = Instant::now();
let sender = self.to_write_tx.clone();
let serial = decoded.serial;
@ -686,7 +679,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
tab.writer().write_all(&data)?;
maybe_push_tab_changes(&surfaces, &tab, sender)?;
Ok(Pdu::UnitResponse(UnitResponse {}))
@ -699,7 +692,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
tab.send_paste(&data)?;
maybe_push_tab_changes(&surfaces, &tab, sender)?;
Ok(Pdu::UnitResponse(UnitResponse {}))
@ -710,7 +703,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
tab.resize(size)?;
Ok(Pdu::UnitResponse(UnitResponse {}))
}),
@ -722,7 +715,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
tab.key_down(event.key, event.modifiers)?;
maybe_push_tab_changes(&surfaces, &tab, sender)?;
Ok(Pdu::UnitResponse(UnitResponse {}))
@ -735,7 +728,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
let mut host = BufferedTerminalHost {
tab_id,
write: tab.writer(),
@ -759,12 +752,12 @@ impl<S: ReadAndWrite> ClientSession<S> {
move || {
let mux = Mux::get().unwrap();
let domain = mux.get_domain(spawn.domain_id).ok_or_else(|| {
format_err!("domain {} not found on this server", spawn.domain_id)
anyhow!("domain {} not found on this server", spawn.domain_id)
})?;
let window_id = if let Some(window_id) = spawn.window_id {
mux.get_window_mut(window_id).ok_or_else(|| {
format_err!("window_id {} not found on this server", window_id)
anyhow!("window_id {} not found on this server", window_id)
})?;
window_id
} else {
@ -793,13 +786,13 @@ impl<S: ReadAndWrite> ClientSession<S> {
let mux = Mux::get().unwrap();
let tab = mux
.get_tab(tab_id)
.ok_or_else(|| format_err!("no such tab {}", tab_id))?;
.ok_or_else(|| anyhow!("no such tab {}", tab_id))?;
maybe_push_tab_changes(&surfaces, &tab, sender)?;
Ok(Pdu::UnitResponse(UnitResponse {}))
})
}
Pdu::Invalid { .. } => Future::err(format_err!("invalid PDU {:?}", pdu)),
Pdu::Invalid { .. } => Future::err(anyhow!("invalid PDU {:?}", pdu)),
Pdu::Pong { .. }
| Pdu::ListTabsResponse { .. }
| Pdu::SendMouseEventResponse { .. }
@ -809,7 +802,7 @@ impl<S: ReadAndWrite> ClientSession<S> {
| Pdu::GetTabRenderChangesResponse { .. }
| Pdu::UnitResponse { .. }
| Pdu::ErrorResponse { .. } => {
Future::err(format_err!("expected a request, got {:?}", pdu))
Future::err(anyhow!("expected a request, got {:?}", pdu))
}
}
}
@ -856,7 +849,7 @@ fn safely_create_sock_path(unix_dom: &UnixDomain) -> Result<UnixListener, Error>
let sock_dir = sock_path
.parent()
.ok_or_else(|| format_err!("sock_path {} has no parent dir", sock_path.display()))?;
.ok_or_else(|| anyhow!("sock_path {} has no parent dir", sock_path.display()))?;
create_user_owned_dirs(sock_dir)?;
@ -886,20 +879,20 @@ fn safely_create_sock_path(unix_dom: &UnixDomain) -> Result<UnixListener, Error>
}
UnixListener::bind(sock_path)
.map_err(|e| format_err!("Failed to bind to {}: {}", sock_path.display(), e))
.with_context(|| format!("Failed to bind to {}", sock_path.display()))
}
#[cfg(any(feature = "openssl", unix))]
fn spawn_tls_listener(tls_server: &TlsDomainServer) -> Fallible<()> {
fn spawn_tls_listener(tls_server: &TlsDomainServer) -> anyhow::Result<()> {
ossl::spawn_tls_listener(tls_server)
}
#[cfg(not(any(feature = "openssl", unix)))]
fn spawn_tls_listener(tls_server: &TlsDomainServer) -> Fallible<()> {
fn spawn_tls_listener(tls_server: &TlsDomainServer) -> anyhow::Result<()> {
not_ossl::spawn_tls_listener(tls_server)
}
pub fn spawn_listener() -> Fallible<()> {
pub fn spawn_listener() -> anyhow::Result<()> {
let config = configuration();
for unix_dom in &config.unix_domains {
let mut listener = LocalListener::new(safely_create_sock_path(unix_dom)?);

View File

@ -1,17 +1,17 @@
use crate::server::UnixStream;
use anyhow::Error;
use crossbeam_channel::{unbounded as channel, Receiver, Sender, TryRecvError};
use failure::{format_err, Fallible};
use filedescriptor::*;
use std::cell::RefCell;
use std::io::{Read, Write};
use std::net::TcpStream;
pub trait ReadAndWrite: std::io::Read + std::io::Write + Send + AsPollFd {
fn set_non_blocking(&self, non_blocking: bool) -> Fallible<()>;
fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()>;
fn has_read_buffered(&self) -> bool;
}
impl ReadAndWrite for UnixStream {
fn set_non_blocking(&self, non_blocking: bool) -> Fallible<()> {
fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()> {
self.set_nonblocking(non_blocking)?;
Ok(())
}
@ -20,7 +20,7 @@ impl ReadAndWrite for UnixStream {
}
}
impl ReadAndWrite for native_tls::TlsStream<std::net::TcpStream> {
fn set_non_blocking(&self, non_blocking: bool) -> Fallible<()> {
fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()> {
self.get_ref().set_nonblocking(non_blocking)?;
Ok(())
}
@ -31,7 +31,7 @@ impl ReadAndWrite for native_tls::TlsStream<std::net::TcpStream> {
#[cfg(any(feature = "openssl", unix))]
impl ReadAndWrite for openssl::ssl::SslStream<std::net::TcpStream> {
fn set_non_blocking(&self, non_blocking: bool) -> Fallible<()> {
fn set_non_blocking(&self, non_blocking: bool) -> anyhow::Result<()> {
self.get_ref().set_nonblocking(non_blocking)?;
Ok(())
}
@ -45,10 +45,10 @@ pub struct PollableSender<T> {
write: RefCell<FileDescriptor>,
}
impl<T> PollableSender<T> {
pub fn send(&self, item: T) -> Fallible<()> {
impl<T: Send + Sync + 'static> PollableSender<T> {
pub fn send(&self, item: T) -> anyhow::Result<()> {
self.write.borrow_mut().write_all(b"x")?;
self.sender.send(item).map_err(|e| format_err!("{}", e))?;
self.sender.send(item).map_err(Error::msg)?;
Ok(())
}
}
@ -92,7 +92,7 @@ impl<T> AsPollFd for PollableReceiver<T> {
/// socketpair.
/// In theory this should also work on windows, but will require
/// windows 10 w/unix domain socket support.
pub fn pollable_channel<T>() -> Fallible<(PollableSender<T>, PollableReceiver<T>)> {
pub fn pollable_channel<T>() -> anyhow::Result<(PollableSender<T>, PollableReceiver<T>)> {
let (sender, receiver) = channel();
let (write, read) = socketpair()?;
Ok((

View File

@ -5,7 +5,7 @@ use crate::mux::tab::{alloc_tab_id, Tab, TabId};
use crate::server::client::Client;
use crate::server::codec::*;
use crate::server::domain::ClientInner;
use failure::{bail, Fallible};
use anyhow::bail;
use filedescriptor::Pipe;
use log::{error, info};
use portable_pty::PtySize;
@ -69,7 +69,7 @@ impl MouseState {
log::trace!("MouseEvent {}: queued", self.queue.len());
}
fn pop(&mut self) -> Fallible<Option<MouseEvent>> {
fn pop(&mut self) -> anyhow::Result<Option<MouseEvent>> {
if self.can_send()? {
Ok(self.queue.pop_front())
} else {
@ -77,7 +77,7 @@ impl MouseState {
}
}
fn can_send(&mut self) -> Fallible<bool> {
fn can_send(&mut self) -> anyhow::Result<bool> {
if self.future.is_none() {
Ok(true)
} else {
@ -91,7 +91,7 @@ impl MouseState {
}
}
fn next(state: &Arc<Mutex<Self>>) -> Fallible<()> {
fn next(state: &Arc<Mutex<Self>>) -> anyhow::Result<()> {
let mut mouse = state.lock().unwrap();
if let Some(event) = mouse.pop()? {
let selection_range = Arc::clone(&mouse.selection_range);
@ -186,7 +186,7 @@ impl ClientTab {
}
}
pub fn process_unilateral(&self, pdu: Pdu) -> Fallible<()> {
pub fn process_unilateral(&self, pdu: Pdu) -> anyhow::Result<()> {
match pdu {
Pdu::GetTabRenderChangesResponse(delta) => {
log::trace!("new delta {}", delta.sequence_no);
@ -244,7 +244,7 @@ impl Tab for ClientTab {
surface.title().to_string()
}
fn send_paste(&self, text: &str) -> Fallible<()> {
fn send_paste(&self, text: &str) -> anyhow::Result<()> {
self.client.client.send_paste(SendPaste {
tab_id: self.remote_tab_id,
data: text.to_owned(),
@ -252,7 +252,7 @@ impl Tab for ClientTab {
Ok(())
}
fn reader(&self) -> Fallible<Box<dyn std::io::Read + Send>> {
fn reader(&self) -> anyhow::Result<Box<dyn std::io::Read + Send>> {
info!("made reader for ClientTab");
Ok(Box::new(self.reader.read.try_clone()?))
}
@ -261,7 +261,7 @@ impl Tab for ClientTab {
self.writer.borrow_mut()
}
fn resize(&self, size: PtySize) -> Fallible<()> {
fn resize(&self, size: PtySize) -> anyhow::Result<()> {
self.renderable
.borrow()
.inner
@ -275,7 +275,7 @@ impl Tab for ClientTab {
Ok(())
}
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> Fallible<()> {
fn key_down(&self, key: KeyCode, mods: KeyModifiers) -> anyhow::Result<()> {
self.client.client.key_down(SendKeyDown {
tab_id: self.remote_tab_id,
event: KeyEvent {
@ -286,7 +286,7 @@ impl Tab for ClientTab {
Ok(())
}
fn mouse_event(&self, event: MouseEvent, _host: &mut dyn TerminalHost) -> Fallible<()> {
fn mouse_event(&self, event: MouseEvent, _host: &mut dyn TerminalHost) -> anyhow::Result<()> {
self.mouse.lock().unwrap().append(event);
MouseState::next(&self.mouse)?;
Ok(())
@ -357,7 +357,7 @@ impl RenderableInner {
self.remote_sequence = remote_seq;
}
fn poll(&mut self) -> Fallible<()> {
fn poll(&mut self) -> anyhow::Result<()> {
let ready = self
.poll_future
.as_ref()

View File

@ -5,8 +5,7 @@ use crate::mux::tab::Tab;
use crate::mux::window::WindowId;
use crate::mux::Mux;
use crate::termwiztermtab;
use failure::Error;
use failure::{bail, format_err, Fallible};
use anyhow::{anyhow, bail, Context, Error};
use portable_pty::cmdbuilder::CommandBuilder;
use portable_pty::{PtySize, PtySystem};
use std::collections::HashSet;
@ -150,7 +149,7 @@ impl<'a> ssh2::KeyboardInteractivePrompt for Prompt<'a> {
}
}
pub fn ssh_connect(remote_address: &str, username: &str) -> Fallible<ssh2::Session> {
pub fn ssh_connect(remote_address: &str, username: &str) -> anyhow::Result<ssh2::Session> {
let mut sess = ssh2::Session::new()?;
let (remote_address, remote_host_name, port) = {
@ -164,28 +163,26 @@ pub fn ssh_connect(remote_address: &str, username: &str) -> Fallible<ssh2::Sessi
};
let tcp = TcpStream::connect(&remote_address)
.map_err(|e| format_err!("ssh connecting to {}: {}", remote_address, e))?;
.with_context(|| format!("ssh connecting to {}", remote_address))?;
tcp.set_nodelay(true)?;
sess.set_tcp_stream(tcp);
sess.handshake()
.map_err(|e| format_err!("ssh handshake with {}: {}", remote_address, e))?;
.with_context(|| format!("ssh handshake with {}", remote_address))?;
if let Ok(mut known_hosts) = sess.known_hosts() {
let varname = if cfg!(windows) { "USERPROFILE" } else { "HOME" };
let var = std::env::var_os(varname)
.ok_or_else(|| failure::format_err!("environment variable {} is missing", varname))?;
.ok_or_else(|| anyhow!("environment variable {} is missing", varname))?;
let file = Path::new(&var).join(".ssh/known_hosts");
if file.exists() {
known_hosts
.read_file(&file, ssh2::KnownHostFileKind::OpenSSH)
.map_err(|e| {
failure::format_err!("reading known_hosts file {}: {}", file.display(), e)
})?;
.with_context(|| format!("reading known_hosts file {}", file.display()))?;
}
let (key, key_type) = sess
.host_key()
.ok_or_else(|| failure::err_msg("failed to get ssh host key"))?;
.ok_or_else(|| anyhow!("failed to get ssh host key"))?;
let fingerprint = sess
.host_key_hash(ssh2::HashType::Sha256)
@ -210,7 +207,7 @@ pub fn ssh_connect(remote_address: &str, username: &str) -> Fallible<ssh2::Sessi
String::from_utf8(res).unwrap()
})
})
.ok_or_else(|| failure::err_msg("failed to get host fingerprint"))?;
.ok_or_else(|| anyhow!("failed to get host fingerprint"))?;
use ssh2::CheckResult;
match known_hosts.check_port(&remote_host_name, port, key) {
@ -251,15 +248,11 @@ pub fn ssh_connect(remote_address: &str, username: &str) -> Fallible<ssh2::Sessi
known_hosts
.add(remote_host_name, key, &remote_address, key_type.into())
.map_err(|e| {
failure::format_err!("adding known_hosts entry in memory: {}", e)
})?;
.context("adding known_hosts entry in memory")?;
known_hosts
.write_file(&file, ssh2::KnownHostFileKind::OpenSSH)
.map_err(|e| {
failure::format_err!("writing known_hosts file {}: {}", file.display(), e)
})?;
.with_context(|| format!("writing known_hosts file {}", file.display()))?;
}
CheckResult::Mismatch => {
termwiztermtab::message_box_ok(&format!(
@ -301,14 +294,14 @@ pub fn ssh_connect(remote_address: &str, username: &str) -> Fallible<ssh2::Sessi
if !sess.authenticated() && methods.contains("password") {
let pass = password_prompt("", "Password", username, &remote_address)
.ok_or_else(|| failure::err_msg("password entry was cancelled"))?;
.ok_or_else(|| anyhow!("password entry was cancelled"))?;
if let Err(err) = sess.userauth_password(username, &pass) {
log::error!("while attempting password auth: {}", err);
}
}
if !sess.authenticated() {
failure::bail!("unable to authenticate session");
bail!("unable to authenticate session");
}
Ok(sess)
@ -376,12 +369,12 @@ impl Domain for RemoteSshDomain {
&self.name
}
fn attach(&self) -> Fallible<()> {
fn attach(&self) -> anyhow::Result<()> {
Ok(())
}
fn detach(&self) -> Fallible<()> {
failure::bail!("detach not implemented");
fn detach(&self) -> anyhow::Result<()> {
bail!("detach not implemented");
}
fn state(&self) -> DomainState {

View File

@ -10,8 +10,8 @@ use crate::mux::renderable::Renderable;
use crate::mux::tab::{alloc_tab_id, Tab, TabId};
use crate::mux::window::WindowId;
use crate::mux::Mux;
use anyhow::{bail, Error};
use crossbeam_channel::{unbounded as channel, Receiver, Sender};
use failure::*;
use filedescriptor::Pipe;
use portable_pty::*;
use promise::{Future, Promise};
@ -155,7 +155,7 @@ impl Domain for TermWizTerminalDomain {
_size: PtySize,
_command: Option<CommandBuilder>,
_window: WindowId,
) -> Fallible<Rc<dyn Tab>> {
) -> anyhow::Result<Rc<dyn Tab>> {
bail!("cannot spawn tabs in a TermWizTerminalTab");
}
@ -166,11 +166,11 @@ impl Domain for TermWizTerminalDomain {
fn domain_name(&self) -> &str {
"TermWizTerminalDomain"
}
fn attach(&self) -> Fallible<()> {
fn attach(&self) -> anyhow::Result<()> {
Ok(())
}
fn detach(&self) -> Fallible<()> {
fn detach(&self) -> anyhow::Result<()> {
bail!("detach not implemented for TermWizTerminalDomain");
}
@ -223,7 +223,7 @@ impl Tab for TermWizTerminalTab {
surface.title().to_string()
}
fn send_paste(&self, text: &str) -> Fallible<()> {
fn send_paste(&self, text: &str) -> anyhow::Result<()> {
let paste = InputEvent::Paste(text.to_string());
self.renderable
.borrow_mut()
@ -234,7 +234,7 @@ impl Tab for TermWizTerminalTab {
Ok(())
}
fn reader(&self) -> Fallible<Box<dyn std::io::Read + Send>> {
fn reader(&self) -> anyhow::Result<Box<dyn std::io::Read + Send>> {
Ok(Box::new(self.reader.read.try_clone()?))
}
@ -242,7 +242,7 @@ impl Tab for TermWizTerminalTab {
self.renderable.borrow_mut()
}
fn resize(&self, size: PtySize) -> Fallible<()> {
fn resize(&self, size: PtySize) -> anyhow::Result<()> {
self.renderable
.borrow()
.inner
@ -252,7 +252,7 @@ impl Tab for TermWizTerminalTab {
Ok(())
}
fn key_down(&self, key: KeyCode, modifiers: KeyModifiers) -> Fallible<()> {
fn key_down(&self, key: KeyCode, modifiers: KeyModifiers) -> anyhow::Result<()> {
let event = InputEvent::Key(KeyEvent { key, modifiers });
self.renderable
.borrow_mut()
@ -263,7 +263,7 @@ impl Tab for TermWizTerminalTab {
Ok(())
}
fn mouse_event(&self, _event: MouseEvent, _host: &mut dyn TerminalHost) -> Fallible<()> {
fn mouse_event(&self, _event: MouseEvent, _host: &mut dyn TerminalHost) -> anyhow::Result<()> {
// FIXME: send mouse events through
Ok(())
}
@ -308,7 +308,7 @@ pub struct TermWizTerminal {
}
impl TermWizTerminal {
fn do_input_poll(&mut self, wait: Option<Duration>) -> Fallible<Option<InputEvent>> {
fn do_input_poll(&mut self, wait: Option<Duration>) -> anyhow::Result<Option<InputEvent>> {
if let Some(timeout) = wait {
match self.input_rx.recv_timeout(timeout) {
Ok(input) => Ok(Some(input)),
@ -328,40 +328,40 @@ impl TermWizTerminal {
}
impl termwiz::terminal::Terminal for TermWizTerminal {
fn set_raw_mode(&mut self) -> Fallible<()> {
fn set_raw_mode(&mut self) -> anyhow::Result<()> {
Ok(())
}
fn set_cooked_mode(&mut self) -> Fallible<()> {
fn set_cooked_mode(&mut self) -> anyhow::Result<()> {
Ok(())
}
fn enter_alternate_screen(&mut self) -> Fallible<()> {
fn enter_alternate_screen(&mut self) -> anyhow::Result<()> {
bail!("TermWizTerminalTab has no alt screen");
}
fn exit_alternate_screen(&mut self) -> Fallible<()> {
fn exit_alternate_screen(&mut self) -> anyhow::Result<()> {
bail!("TermWizTerminalTab has no alt screen");
}
fn get_screen_size(&mut self) -> Fallible<ScreenSize> {
fn get_screen_size(&mut self) -> anyhow::Result<ScreenSize> {
Ok(self.screen_size)
}
fn set_screen_size(&mut self, _size: ScreenSize) -> Fallible<()> {
fn set_screen_size(&mut self, _size: ScreenSize) -> anyhow::Result<()> {
bail!("TermWizTerminalTab cannot set screen size");
}
fn render(&mut self, changes: &[Change]) -> Fallible<()> {
fn render(&mut self, changes: &[Change]) -> anyhow::Result<()> {
self.render_tx.send(changes.to_vec())?;
Ok(())
}
fn flush(&mut self) -> Fallible<()> {
fn flush(&mut self) -> anyhow::Result<()> {
Ok(())
}
fn poll_input(&mut self, wait: Option<Duration>) -> Fallible<Option<InputEvent>> {
fn poll_input(&mut self, wait: Option<Duration>) -> anyhow::Result<Option<InputEvent>> {
self.do_input_poll(wait).map(|i| {
if let Some(InputEvent::Resized { cols, rows }) = i.as_ref() {
self.screen_size.cols = *cols;
@ -384,7 +384,7 @@ impl termwiz::terminal::Terminal for TermWizTerminal {
/// from the terminal window.
/// When it completes its loop it will fulfil a promise and yield
/// the return value from the function.
pub fn run<T: Send + 'static, F: Send + 'static + Fn(TermWizTerminal) -> Fallible<T>>(
pub fn run<T: Send + 'static, F: Send + 'static + Fn(TermWizTerminal) -> anyhow::Result<T>>(
width: usize,
height: usize,
f: F,
@ -454,7 +454,8 @@ pub fn message_box_ok(message: &str) {
term.render(&[
Change::Title(title.to_string()),
Change::Text(message.to_string()),
])?;
])
.map_err(Error::msg)?;
let mut editor = LineEditor::new(term);
editor.set_prompt("press enter to continue.");

View File

@ -6,7 +6,7 @@ edition = "2018"
[dependencies]
bitflags = "1.0"
failure = "0.1"
anyhow = "1.0"
image = "0.21"
log = "0.4"
num = "0.2"

View File

@ -1,7 +1,7 @@
//! Terminal model
use serde_derive::*;
use failure::Error;
use anyhow::Error;
use std::ops::{Deref, DerefMut, Range};
use std::str;

View File

@ -1,19 +1,18 @@
use super::*;
use failure::Fallible;
use std::sync::Arc;
use termwiz::escape::parser::Parser;
pub trait Clipboard {
fn get_contents(&self) -> Fallible<String>;
fn set_contents(&self, data: Option<String>) -> Fallible<()>;
fn get_contents(&self) -> anyhow::Result<String>;
fn set_contents(&self, data: Option<String>) -> anyhow::Result<()>;
}
impl Clipboard for Box<dyn Clipboard> {
fn get_contents(&self) -> Fallible<String> {
fn get_contents(&self) -> anyhow::Result<String> {
self.as_ref().get_contents()
}
fn set_contents(&self, data: Option<String>) -> Fallible<()> {
fn set_contents(&self, data: Option<String>) -> anyhow::Result<()> {
self.as_ref().set_contents(data)
}
}

View File

@ -3,7 +3,7 @@
#![cfg_attr(feature = "cargo-clippy", allow(clippy::range_plus_one))]
use super::*;
use crate::color::ColorPalette;
use failure::{bail, Fallible};
use anyhow::bail;
use image::{self, GenericImageView};
use log::{debug, error};
use ordered_float::NotNan;
@ -479,14 +479,14 @@ impl TerminalState {
self.invalidate_hyperlinks();
}
fn set_clipboard_contents(&self, text: Option<String>) -> Fallible<()> {
fn set_clipboard_contents(&self, text: Option<String>) -> anyhow::Result<()> {
if let Some(clip) = self.clipboard.as_ref() {
clip.set_contents(text)?;
}
Ok(())
}
fn get_clipboard_contents(&self) -> Fallible<String> {
fn get_clipboard_contents(&self) -> anyhow::Result<String> {
if let Some(clip) = self.clipboard.as_ref() {
clip.get_contents()
} else {

View File

@ -6,7 +6,6 @@ mod c0;
use bitflags::bitflags;
mod c1;
mod csi;
use failure::Fallible;
mod selection;
use pretty_assertions::assert_eq;
use std::cell::RefCell;
@ -49,17 +48,17 @@ impl LocalClip {
}
impl Clipboard for LocalClip {
fn set_contents(&self, clip: Option<String>) -> Fallible<()> {
fn set_contents(&self, clip: Option<String>) -> anyhow::Result<()> {
*self.clip.borrow_mut() = clip;
Ok(())
}
fn get_contents(&self) -> Fallible<String> {
fn get_contents(&self) -> anyhow::Result<String> {
self.clip
.borrow()
.as_ref()
.map(|c| c.clone())
.ok_or_else(|| failure::err_msg("no clipboard"))
.ok_or_else(|| anyhow::anyhow!("no clipboard"))
}
}

View File

@ -15,8 +15,8 @@ base64 = "0.10"
bitflags = "1.0"
cassowary = "0.3"
derive_builder = "0.7"
failure = "0.1"
filedescriptor = "0.5"
anyhow = "1.0"
filedescriptor = "0.6"
fnv = "1.0"
image = "0.21"
libc = "0.2"

View File

@ -2,7 +2,7 @@
//! up changes and then flush them. `BufferedTerminal` enables
//! optimizing the output sequence to update the screen, which is
//! important on links with poor connectivity.
use failure::Error;
use anyhow::Error;
use termwiz::caps::Capabilities;
use termwiz::cell::AttributeChange;
use termwiz::color::AnsiColor;

View File

@ -1,4 +1,4 @@
use failure::Error;
use anyhow::Error;
use termwiz::caps::Capabilities;
use termwiz::cell::AttributeChange;
use termwiz::color::AnsiColor;

View File

@ -1,4 +1,4 @@
use failure::Error;
use anyhow::Error;
use termwiz::caps::Capabilities;
use termwiz::input::{InputEvent, KeyCode, KeyEvent, Modifiers};
use termwiz::terminal::{new_terminal, Terminal};

View File

@ -1,4 +1,3 @@
use failure::Fallible;
use termwiz::cell::AttributeChange;
use termwiz::color::{AnsiColor, ColorAttribute, RgbColor};
use termwiz::lineedit::*;
@ -91,7 +90,7 @@ fn word_at_cursor(line: &str, cursor_position: usize) -> Option<(std::ops::Range
}
}
fn main() -> Fallible<()> {
fn main() -> anyhow::Result<()> {
println!("Type `exit` to quit this example, or start a word with `h` and press Tab.");
let mut editor = line_editor()?;

View File

@ -5,7 +5,7 @@
//! the `buffered_terminal.rs` example demonstrates a simple
//! way to enable optimizations.
use failure::Error;
use anyhow::Error;
use termwiz::caps::Capabilities;
use termwiz::cell::AttributeChange;
use termwiz::color::AnsiColor;

View File

@ -1,6 +1,6 @@
//! This example shows how to make a basic widget that accumulates
//! text input and renders it to the screen
use failure::Error;
use anyhow::Error;
use termwiz::caps::Capabilities;
use termwiz::cell::AttributeChange;
use termwiz::color::{AnsiColor, ColorAttribute, RgbColor};

View File

@ -54,8 +54,8 @@
//! implements some heuristics (a fancy word for guessing) to compute
//! the terminal capabilities, but also offers a `ProbeHintsBuilder`
//! that can be used by the embedding application to override those choices.
use anyhow::Error;
use derive_builder::*;
use failure::{err_msg, Error};
use semver::Version;
use std::env::var;
use terminfo::{self, capability as cap};
@ -164,7 +164,11 @@ impl Capabilities {
/// This function inspects the environment variables to build
/// up configuration hints.
pub fn new_from_env() -> Result<Self, Error> {
Self::new_with_hints(ProbeHintsBuilder::new_from_env().build().map_err(err_msg)?)
Self::new_with_hints(
ProbeHintsBuilder::new_from_env()
.build()
.map_err(Error::msg)?,
)
}
/// Build a `Capabilities` object based on the provided `ProbeHints` object.

View File

@ -1,8 +1,8 @@
use crate::color::RgbColor;
pub use crate::hyperlink::Hyperlink;
use anyhow::{anyhow, bail, ensure};
use base64;
use bitflags::bitflags;
use failure::{bail, ensure, err_msg, Fallible};
use num;
use num_derive::*;
use ordered_float::NotNan;
@ -83,7 +83,7 @@ pub struct Selection :u16{
}
impl Selection {
fn try_parse(buf: &[u8]) -> Fallible<Selection> {
fn try_parse(buf: &[u8]) -> anyhow::Result<Selection> {
if buf == b"" {
Ok(Selection::SELECT | Selection::CUT0)
} else {
@ -149,7 +149,7 @@ impl OperatingSystemCommand {
})
}
fn parse_selection(osc: &[&[u8]]) -> Fallible<Self> {
fn parse_selection(osc: &[&[u8]]) -> anyhow::Result<Self> {
if osc.len() == 2 {
Selection::try_parse(osc[1]).map(OperatingSystemCommand::ClearSelection)
} else if osc.len() == 3 && osc[2] == b"?" {
@ -164,7 +164,7 @@ impl OperatingSystemCommand {
}
}
fn parse_change_color_number(osc: &[&[u8]]) -> Fallible<Self> {
fn parse_change_color_number(osc: &[&[u8]]) -> anyhow::Result<Self> {
let mut pairs = vec![];
let mut iter = osc.iter();
iter.next(); // skip the command word that we already know is present
@ -177,7 +177,7 @@ impl OperatingSystemCommand {
} else {
ColorOrQuery::Color(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| err_msg("invalid color spec"))?,
.ok_or_else(|| anyhow!("invalid color spec"))?,
)
};
@ -190,9 +190,9 @@ impl OperatingSystemCommand {
Ok(OperatingSystemCommand::ChangeColorNumber(pairs))
}
fn parse_change_dynamic_color_number(idx: u8, osc: &[&[u8]]) -> Fallible<Self> {
fn parse_change_dynamic_color_number(idx: u8, osc: &[&[u8]]) -> anyhow::Result<Self> {
let which_color: DynamicColorNumber = num::FromPrimitive::from_u8(idx)
.ok_or_else(|| err_msg("osc code is not a valid DynamicColorNumber!?"))?;
.ok_or_else(|| anyhow!("osc code is not a valid DynamicColorNumber!?"))?;
let mut colors = vec![];
for spec in osc.iter().skip(1) {
if spec == b"?" {
@ -201,7 +201,7 @@ impl OperatingSystemCommand {
let spec = str::from_utf8(spec)?;
colors.push(ColorOrQuery::Color(
RgbColor::from_named_or_rgb_string(spec)
.ok_or_else(|| err_msg("invalid color spec"))?,
.ok_or_else(|| anyhow!("invalid color spec"))?,
));
}
}
@ -212,12 +212,12 @@ impl OperatingSystemCommand {
))
}
fn internal_parse(osc: &[&[u8]]) -> Fallible<Self> {
fn internal_parse(osc: &[&[u8]]) -> anyhow::Result<Self> {
ensure!(!osc.is_empty(), "no params");
let p1str = String::from_utf8_lossy(osc[0]);
let code: i64 = p1str.parse()?;
let osc_code: OperatingSystemCommandCode =
num::FromPrimitive::from_i64(code).ok_or_else(|| err_msg("unknown code"))?;
num::FromPrimitive::from_i64(code).ok_or_else(|| anyhow!("unknown code"))?;
macro_rules! single_string {
($variant:ident) => {{
@ -405,7 +405,7 @@ pub struct ITermFileData {
}
impl ITermFileData {
fn parse(osc: &[&[u8]]) -> Fallible<Self> {
fn parse(osc: &[&[u8]]) -> anyhow::Result<Self> {
let mut params = HashMap::new();
// Unfortunately, the encoding for the file download data is
@ -468,7 +468,7 @@ impl ITermFileData {
.map(|s| *s != "0")
.unwrap_or(true);
let inline = params.get("inline").map(|s| *s != "0").unwrap_or(false);
let data = data.ok_or_else(|| err_msg("didn't set data"))?;
let data = data.ok_or_else(|| anyhow!("didn't set data"))?;
Ok(Self {
name,
size,
@ -550,14 +550,14 @@ impl Display for ITermDimension {
}
impl std::str::FromStr for ITermDimension {
type Err = failure::Error;
fn from_str(s: &str) -> Fallible<Self> {
type Err = anyhow::Error;
fn from_str(s: &str) -> anyhow::Result<Self> {
ITermDimension::parse(s)
}
}
impl ITermDimension {
fn parse(s: &str) -> Fallible<Self> {
fn parse(s: &str) -> anyhow::Result<Self> {
if s == "auto" {
Ok(ITermDimension::Automatic)
} else if s.ends_with("px") {
@ -595,7 +595,7 @@ impl ITermProprietary {
feature = "cargo-clippy",
allow(clippy::cyclomatic_complexity, clippy::cognitive_complexity)
)]
fn parse(osc: &[&[u8]]) -> Fallible<Self> {
fn parse(osc: &[&[u8]]) -> anyhow::Result<Self> {
// iTerm has a number of different styles of OSC parameter
// encodings, which makes this section of code a bit gnarly.
ensure!(osc.len() > 1, "not enough args");
@ -603,7 +603,7 @@ impl ITermProprietary {
let param = String::from_utf8_lossy(osc[1]);
let mut iter = param.splitn(2, '=');
let keyword = iter.next().ok_or_else(|| err_msg("bad params"))?;
let keyword = iter.next().ok_or_else(|| anyhow!("bad params"))?;
let p1 = iter.next();
macro_rules! single {

View File

@ -4,7 +4,7 @@
//! We use that as the foundation of our hyperlink support, and the game
//! plan is to then implicitly enable the hyperlink attribute for a cell
//! as we recognize linkable input text during print() processing.
use failure::{ensure, err_msg, Error};
use anyhow::{anyhow, ensure, Error};
use regex::{Captures, Regex};
use serde::{self, Deserialize, Deserializer};
use serde_derive::*;
@ -83,8 +83,8 @@ impl Hyperlink {
if !param_str.is_empty() {
for pair in param_str.split(':') {
let mut iter = pair.splitn(2, '=');
let key = iter.next().ok_or_else(|| err_msg("bad params"))?;
let value = iter.next().ok_or_else(|| err_msg("bad params"))?;
let key = iter.next().ok_or_else(|| anyhow!("bad params"))?;
let value = iter.next().ok_or_else(|| anyhow!("bad params"))?;
params.insert(key.to_owned(), value.to_owned());
}
}

View File

@ -2,10 +2,9 @@
//! to those in the unix shell.
//!
//! ```no_run
//! use failure::Fallible;
//! use termwiz::lineedit::{line_editor, NopLineEditorHost};
//!
//! fn main() -> Fallible<()> {
//! fn main() -> anyhow::Result<()> {
//! let mut editor = line_editor()?;
//! let mut host = NopLineEditorHost::default();
//!
@ -40,7 +39,7 @@ use crate::cell::unicode_column_width;
use crate::input::{InputEvent, KeyCode, KeyEvent, Modifiers};
use crate::surface::{Change, Position};
use crate::terminal::{new_terminal, Terminal};
use failure::{err_msg, Fallible};
use anyhow::Error;
use unicode_segmentation::GraphemeCursor;
mod actions;
@ -53,10 +52,9 @@ pub use host::*;
/// The `LineEditor` struct provides line editing facilities similar
/// to those in the unix shell.
/// ```no_run
/// use failure::Fallible;
/// use termwiz::lineedit::{line_editor, NopLineEditorHost};
///
/// fn main() -> Fallible<()> {
/// fn main() -> anyhow::Result<()> {
/// let mut editor = line_editor()?;
/// let mut host = NopLineEditorHost::default();
///
@ -122,15 +120,15 @@ impl<T: Terminal> LineEditor<T> {
/// ```no_run
/// use termwiz::caps::{Capabilities, ProbeHintsBuilder};
/// use termwiz::terminal::new_terminal;
/// use failure::err_msg;
/// use anyhow::Error;
/// // Disable mouse input in the line editor
/// let hints = ProbeHintsBuilder::new_from_env()
/// .mouse_reporting(Some(false))
/// .build()
/// .map_err(err_msg)?;
/// .map_err(Error::msg)?;
/// let caps = Capabilities::new_with_hints(hints)?;
/// let terminal = new_terminal(caps)?;
/// # Ok::<(), failure::Error>(())
/// # Ok::<(), Error>(())
/// ```
pub fn new(terminal: T) -> Self {
Self {
@ -144,7 +142,7 @@ impl<T: Terminal> LineEditor<T> {
}
}
fn render(&mut self, host: &mut dyn LineEditorHost) -> Fallible<()> {
fn render(&mut self, host: &mut dyn LineEditorHost) -> anyhow::Result<()> {
let mut changes = vec![
Change::CursorPosition {
x: Position::Absolute(0),
@ -184,7 +182,7 @@ impl<T: Terminal> LineEditor<T> {
/// Control is not returned to the caller until a line has been
/// accepted, or until an error is detected.
/// Returns Ok(None) if the editor was cancelled eg: via CTRL-C.
pub fn read_line(&mut self, host: &mut dyn LineEditorHost) -> Fallible<Option<String>> {
pub fn read_line(&mut self, host: &mut dyn LineEditorHost) -> anyhow::Result<Option<String>> {
self.terminal.set_raw_mode()?;
let res = self.read_line_impl(host);
self.terminal.set_cooked_mode()?;
@ -446,7 +444,7 @@ impl<T: Terminal> LineEditor<T> {
self.completion = None;
}
fn read_line_impl(&mut self, host: &mut dyn LineEditorHost) -> Fallible<Option<String>> {
fn read_line_impl(&mut self, host: &mut dyn LineEditorHost) -> anyhow::Result<Option<String>> {
self.line.clear();
self.cursor = 0;
self.history_pos = None;
@ -561,11 +559,11 @@ impl<T: Terminal> LineEditor<T> {
/// Create a `Terminal` with the recommended settings, and use that
/// to create a `LineEditor` instance.
pub fn line_editor() -> Fallible<LineEditor<impl Terminal>> {
pub fn line_editor() -> anyhow::Result<LineEditor<impl Terminal>> {
let hints = ProbeHintsBuilder::new_from_env()
.mouse_reporting(Some(false))
.build()
.map_err(err_msg)?;
.map_err(Error::msg)?;
let caps = Capabilities::new_with_hints(hints)?;
let terminal = new_terminal(caps)?;
Ok(LineEditor::new(terminal))

View File

@ -8,7 +8,6 @@ use crate::escape::OneBased;
use crate::image::TextureCoordinate;
use crate::surface::{Change, CursorShape, Position};
use crate::terminal::unix::UnixTty;
use failure::Fallible;
use log::error;
use std::io::{Read, Write};
use terminfo::{capability as cap, Capability as TermInfoCapability};
@ -49,7 +48,7 @@ impl TerminfoRenderer {
}
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cognitive_complexity))]
fn flush_pending_attr<W: UnixTty + Write>(&mut self, out: &mut W) -> Fallible<()> {
fn flush_pending_attr<W: UnixTty + Write>(&mut self, out: &mut W) -> anyhow::Result<()> {
macro_rules! attr_on {
($cap:ident, $sgr:expr) => {
if let Some(attr) = self.get_capability::<cap::$cap>() {
@ -206,7 +205,7 @@ impl TerminfoRenderer {
Ok(())
}
fn cursor_up<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> Fallible<()> {
fn cursor_up<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> {
if let Some(attr) = self.get_capability::<cap::ParmUpCursor>() {
attr.expand().count(n).to(out.by_ref())?;
} else {
@ -214,7 +213,7 @@ impl TerminfoRenderer {
}
Ok(())
}
fn cursor_down<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> Fallible<()> {
fn cursor_down<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> {
if let Some(attr) = self.get_capability::<cap::ParmDownCursor>() {
attr.expand().count(n).to(out.by_ref())?;
} else {
@ -223,7 +222,7 @@ impl TerminfoRenderer {
Ok(())
}
fn cursor_left<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> Fallible<()> {
fn cursor_left<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> {
if let Some(attr) = self.get_capability::<cap::ParmLeftCursor>() {
attr.expand().count(n).to(out.by_ref())?;
} else {
@ -231,7 +230,7 @@ impl TerminfoRenderer {
}
Ok(())
}
fn cursor_right<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> Fallible<()> {
fn cursor_right<W: UnixTty + Write>(&mut self, n: u32, out: &mut W) -> anyhow::Result<()> {
if let Some(attr) = self.get_capability::<cap::ParmRightCursor>() {
attr.expand().count(n).to(out.by_ref())?;
} else {
@ -251,7 +250,7 @@ impl TerminfoRenderer {
changes: &[Change],
_read: &mut R,
out: &mut W,
) -> Fallible<()> {
) -> anyhow::Result<()> {
macro_rules! record {
($accesor:ident, $value:expr) => {
self.attr_apply(|attr| {
@ -680,7 +679,7 @@ mod test {
use crate::terminal::unix::{Purge, SetAttributeWhen, UnixTty};
use crate::terminal::ScreenSize;
use crate::terminal::{cast, Terminal, TerminalWaker};
use failure::{bail, Fallible};
use anyhow::bail;
use libc::winsize;
use std::io::{Error as IoError, ErrorKind, Read, Result as IoResult, Write};
use std::mem;
@ -738,25 +737,29 @@ mod test {
}
impl UnixTty for FakeTty {
fn get_size(&mut self) -> Fallible<winsize> {
fn get_size(&mut self) -> anyhow::Result<winsize> {
Ok(self.size.clone())
}
fn set_size(&mut self, size: winsize) -> Fallible<()> {
fn set_size(&mut self, size: winsize) -> anyhow::Result<()> {
self.size = size.clone();
Ok(())
}
fn get_termios(&mut self) -> Fallible<Termios> {
fn get_termios(&mut self) -> anyhow::Result<Termios> {
Ok(self.termios.clone())
}
fn set_termios(&mut self, termios: &Termios, _when: SetAttributeWhen) -> Fallible<()> {
fn set_termios(
&mut self,
termios: &Termios,
_when: SetAttributeWhen,
) -> anyhow::Result<()> {
self.termios = termios.clone();
Ok(())
}
/// Waits until all written data has been transmitted.
fn drain(&mut self) -> Fallible<()> {
fn drain(&mut self) -> anyhow::Result<()> {
Ok(())
}
fn purge(&mut self, _purge: Purge) -> Fallible<()> {
fn purge(&mut self, _purge: Purge) -> anyhow::Result<()> {
Ok(())
}
}
@ -805,28 +808,28 @@ mod test {
}
impl Terminal for FakeTerm {
fn set_raw_mode(&mut self) -> Fallible<()> {
fn set_raw_mode(&mut self) -> anyhow::Result<()> {
bail!("not implemented");
}
fn set_cooked_mode(&mut self) -> Fallible<()> {
fn set_cooked_mode(&mut self) -> anyhow::Result<()> {
bail!("not implemented");
}
fn enter_alternate_screen(&mut self) -> Fallible<()> {
fn enter_alternate_screen(&mut self) -> anyhow::Result<()> {
bail!("not implemented");
}
fn exit_alternate_screen(&mut self) -> Fallible<()> {
fn exit_alternate_screen(&mut self) -> anyhow::Result<()> {
bail!("not implemented");
}
fn render(&mut self, changes: &[Change]) -> Fallible<()> {
fn render(&mut self, changes: &[Change]) -> anyhow::Result<()> {
self.renderer
.render_to(changes, &mut self.read, &mut self.write)
}
fn get_screen_size(&mut self) -> Fallible<ScreenSize> {
fn get_screen_size(&mut self) -> anyhow::Result<ScreenSize> {
let size = self.write.get_size()?;
Ok(ScreenSize {
rows: cast(size.ws_row)?,
@ -836,7 +839,7 @@ mod test {
})
}
fn set_screen_size(&mut self, size: ScreenSize) -> Fallible<()> {
fn set_screen_size(&mut self, size: ScreenSize) -> anyhow::Result<()> {
let size = winsize {
ws_row: cast(size.rows)?,
ws_col: cast(size.cols)?,
@ -847,11 +850,11 @@ mod test {
self.write.set_size(size)
}
fn flush(&mut self) -> Fallible<()> {
fn flush(&mut self) -> anyhow::Result<()> {
Ok(())
}
fn poll_input(&mut self, _wait: Option<Duration>) -> Fallible<Option<InputEvent>> {
fn poll_input(&mut self, _wait: Option<Duration>) -> anyhow::Result<Option<InputEvent>> {
bail!("not implemented");
}

View File

@ -2,7 +2,7 @@
use crate::surface::{SequenceNo, Surface};
use crate::terminal::Terminal;
use failure::Error;
use anyhow::Error;
use std::ops::{Deref, DerefMut};
/// `BufferedTerminal` is a convenience wrapper around both

View File

@ -3,7 +3,7 @@
use crate::caps::Capabilities;
use crate::input::InputEvent;
use crate::surface::Change;
use failure::{format_err, Error, Fallible};
use anyhow::{anyhow, Error};
use num::{self, NumCast};
use std::fmt::Display;
use std::time::Duration;
@ -56,7 +56,7 @@ pub trait Terminal {
/// pressed by the user do not implicitly render to the terminal
/// output, and disables canonicalization of unix newlines to CRLF.
fn set_raw_mode(&mut self) -> Result<(), Error>;
fn set_cooked_mode(&mut self) -> Fallible<()>;
fn set_cooked_mode(&mut self) -> anyhow::Result<()>;
/// Enter the alternate screen. The alternate screen will be left
/// automatically when the `Terminal` is dropped.
@ -117,5 +117,5 @@ pub fn new_terminal(caps: Capabilities) -> Result<impl Terminal, Error> {
}
pub(crate) fn cast<T: NumCast + Display + Copy, U: NumCast>(n: T) -> Result<U, Error> {
num::cast(n).ok_or_else(|| format_err!("{} is out of bounds for this system", n))
num::cast(n).ok_or_else(|| anyhow!("{} is out of bounds for this system", n))
}

View File

@ -1,4 +1,4 @@
use failure::{bail, format_err, Error, Fallible};
use anyhow::{anyhow, bail, Context, Error};
use filedescriptor::{poll, pollfd, FileDescriptor, POLLIN};
use libc::{self, winsize};
use signal_hook::{self, SigId};
@ -146,7 +146,7 @@ impl UnixTty for TtyWriteHandle {
}
fn get_termios(&mut self) -> Result<Termios, Error> {
Termios::from_fd(self.fd.as_raw_fd()).map_err(|e| format_err!("get_termios failed: {}", e))
Termios::from_fd(self.fd.as_raw_fd()).context("get_termios failed")
}
fn set_termios(&mut self, termios: &Termios, when: SetAttributeWhen) -> Result<(), Error> {
@ -155,12 +155,11 @@ impl UnixTty for TtyWriteHandle {
SetAttributeWhen::AfterDrainOutputQueue => TCSADRAIN,
SetAttributeWhen::AfterDrainOutputQueuePurgeInputQueue => TCSAFLUSH,
};
tcsetattr(self.fd.as_raw_fd(), when, termios)
.map_err(|e| format_err!("set_termios failed: {}", e))
tcsetattr(self.fd.as_raw_fd(), when, termios).context("set_termios failed")
}
fn drain(&mut self) -> Result<(), Error> {
tcdrain(self.fd.as_raw_fd()).map_err(|e| format_err!("tcdrain failed: {}", e))
tcdrain(self.fd.as_raw_fd()).context("tcdrain failed")
}
fn purge(&mut self, purge: Purge) -> Result<(), Error> {
@ -169,7 +168,7 @@ impl UnixTty for TtyWriteHandle {
Purge::OutputQueue => TCOFLUSH,
Purge::InputAndOutputQueue => TCIOFLUSH,
};
tcflush(self.fd.as_raw_fd(), param).map_err(|e| format_err!("tcflush failed: {}", e))
tcflush(self.fd.as_raw_fd(), param).context("tcflush failed")
}
}
@ -263,7 +262,7 @@ impl UnixTerminal {
{
Ok(None)
}
Err(e) => Err(format_err!("failed to read sigwinch pipe {}", e)),
Err(e) => Err(anyhow!("failed to read sigwinch pipe {}", e)),
}
}
}
@ -287,7 +286,7 @@ impl Terminal for UnixTerminal {
cfmakeraw(&mut raw);
self.write
.set_termios(&raw, SetAttributeWhen::AfterDrainOutputQueuePurgeInputQueue)
.map_err(|e| format_err!("failed to set raw mode: {}", e))?;
.context("failed to set raw mode")?;
macro_rules! decset {
($variant:ident) => {
@ -313,7 +312,7 @@ impl Terminal for UnixTerminal {
Ok(())
}
fn set_cooked_mode(&mut self) -> Fallible<()> {
fn set_cooked_mode(&mut self) -> anyhow::Result<()> {
self.write
.set_termios(&self.saved_termios, SetAttributeWhen::Now)
}
@ -371,9 +370,7 @@ impl Terminal for UnixTerminal {
.render_to(changes, &mut self.read, &mut self.write)
}
fn flush(&mut self) -> Result<(), Error> {
self.write
.flush()
.map_err(|e| format_err!("flush failed: {}", e))
self.write.flush().context("flush failed")
}
fn poll_input(&mut self, wait: Option<Duration>) -> Result<Option<InputEvent>, Error> {
@ -423,10 +420,10 @@ impl Terminal for UnixTerminal {
Ok(None)
}
} else {
Err(format_err!("poll(2) error: {}", err))
Err(anyhow!("poll(2) error: {}", err))
}
}
Err(err) => Err(format_err!("poll(2) error: {}", err)),
Err(err) => Err(anyhow!("poll(2) error: {}", err)),
};
};
@ -451,7 +448,7 @@ impl Terminal for UnixTerminal {
}
Err(ref e)
if e.kind() == ErrorKind::WouldBlock || e.kind() == ErrorKind::Interrupted => {}
Err(e) => return Err(format_err!("failed to read input {}", e)),
Err(e) => return Err(anyhow!("failed to read input {}", e)),
}
}

View File

@ -1,10 +1,10 @@
//! This module provides some automatic layout functionality for widgets.
//! The parameters are similar to those that you may have encountered
//! in HTML, but do not fully recreate the layout model.
use anyhow::{anyhow, Error};
use cassowary::strength::{REQUIRED, STRONG, WEAK};
use cassowary::WeightedRelation::*;
use cassowary::{AddConstraintError, Expression, Solver, SuggestValueError, Variable};
use failure::{err_msg, format_err, Error};
use std::collections::HashMap;
use crate::widgets::{Rect, WidgetId};
@ -185,13 +185,13 @@ pub struct LaidOutWidget {
fn suggesterr(e: SuggestValueError) -> Error {
match e {
SuggestValueError::UnknownEditVariable => err_msg("Unknown edit variable"),
SuggestValueError::InternalSolverError(e) => format_err!("Internal solver error: {}", e),
SuggestValueError::UnknownEditVariable => anyhow!("Unknown edit variable"),
SuggestValueError::InternalSolverError(e) => anyhow!("Internal solver error: {}", e),
}
}
fn adderr(e: AddConstraintError) -> Error {
format_err!("{:?}", e)
anyhow!("{:?}", e)
}
impl Default for LayoutState {
@ -283,7 +283,7 @@ impl LayoutState {
let state = self
.widget_states
.get(&widget)
.ok_or_else(|| err_msg("widget has no solver state"))?;
.ok_or_else(|| anyhow!("widget has no solver state"))?;
let width = self.solver.get_value(state.width) as usize;
let height = self.solver.get_value(state.height) as usize;
let left = self.solver.get_value(state.left) as usize;
@ -317,7 +317,7 @@ impl LayoutState {
let state = self
.widget_states
.get(&widget)
.ok_or_else(|| err_msg("widget has no solver state"))?
.ok_or_else(|| anyhow!("widget has no solver state"))?
.clone();
let is_root_widget = parent_left.is_none();

View File

@ -4,7 +4,7 @@
use crate::color::ColorAttribute;
use crate::input::InputEvent;
use crate::surface::{Change, CursorShape, Position, SequenceNo, Surface};
use failure::Error;
use anyhow::Error;
use fnv::FnvHasher;
use std::collections::{HashMap, VecDeque};
use std::hash::BuildHasherDefault;

View File

@ -15,10 +15,10 @@ pretty_env_logger = "0.3"
gl_generator = {version="0.13", optional=true}
[dependencies]
anyhow = "1.0"
thiserror = "1.0"
bitflags = "1.0"
euclid = "0.20"
failure = "0.1"
failure_derive = "0.1"
lazy_static = "1.3"
libloading = { version = "0.5", optional=true }
line_drawing = "0.8"
@ -46,7 +46,7 @@ winapi = { version = "0.3", features = [
clipboard-win = "2.2"
[target.'cfg(all(unix, not(target_os = "macos")))'.dependencies]
filedescriptor = "0.5"
filedescriptor = "0.6"
x11 = {version ="2.18", features = ["xlib_xcb"]}
xcb = "0.8"
xcb-util = { features = [ "icccm", "ewmh", "keysyms", "shm"], version = "0.2" }

View File

@ -1,5 +1,4 @@
use ::window::*;
use failure::Fallible;
use std::any::Any;
struct MyWindow {
@ -89,7 +88,7 @@ async fn spawn_window() -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn main() -> Fallible<()> {
fn main() -> anyhow::Result<()> {
let conn = Connection::init()?;
conn.spawn_task(async {
eprintln!("running this async block");

View File

@ -1,5 +1,4 @@
use ::window::*;
use failure::Fallible;
use std::any::Any;
struct MyWindow {
@ -83,7 +82,7 @@ impl WindowCallbacks for MyWindow {
}
}
fn spawn_window() -> Fallible<()> {
fn spawn_window() -> anyhow::Result<()> {
let win = Window::new_window(
"myclass",
"the title",
@ -108,7 +107,7 @@ fn spawn_window() -> Fallible<()> {
Ok(())
}
fn main() -> Fallible<()> {
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
let conn = Connection::init()?;
spawn_window()?;

View File

@ -1,5 +1,4 @@
use ::window::*;
use failure::Fallible;
use std::any::Any;
struct MyWindow {
@ -29,7 +28,7 @@ impl WindowCallbacks for MyWindow {
}
}
fn spawn_window() -> Fallible<()> {
fn spawn_window() -> anyhow::Result<()> {
let win = Window::new_window(
"myclass",
"the title",
@ -68,7 +67,7 @@ fn spawn_window() -> Fallible<()> {
Ok(())
}
fn main() -> Fallible<()> {
fn main() -> anyhow::Result<()> {
pretty_env_logger::init();
let conn = Connection::init()?;
spawn_window()?;

View File

@ -1,13 +1,13 @@
use crate::bitmaps::{BitmapImage, Texture2d, TextureRect};
use crate::{Point, Rect, Size};
use failure::{ensure, Fallible};
use failure_derive::*;
use anyhow::{ensure, Result as Fallible};
use std::rc::Rc;
use thiserror::*;
pub const TEX_SIZE: u32 = 4096;
#[derive(Debug, Fail)]
#[fail(display = "Texture Size exceeded, need {}", size)]
#[derive(Debug, Error)]
#[error("Texture Size exceeded, need {}", size)]
pub struct OutOfTextureSpace {
pub size: usize,
}

View File

@ -1,5 +1,5 @@
use crate::Connection;
use failure::Fallible;
use anyhow::Result as Fallible;
use std::cell::RefCell;
use std::rc::Rc;

View File

@ -1,4 +1,4 @@
use failure::Fallible;
use anyhow::{anyhow, bail, ensure, Error};
use std::ffi::c_void;
#[allow(non_camel_case_types, clippy::unreadable_literal)]
@ -54,7 +54,7 @@ type GetProcAddressFunc =
unsafe extern "C" fn(*const std::os::raw::c_char) -> *const std::os::raw::c_void;
impl EglWrapper {
pub fn load_egl(lib: libloading::Library) -> Fallible<Self> {
pub fn load_egl(lib: libloading::Library) -> anyhow::Result<Self> {
let get_proc_address: libloading::Symbol<GetProcAddressFunc> =
unsafe { lib.get(b"eglGetProcAddress\0")? };
let egl = ffi::Egl::load_with(|s: &'static str| {
@ -70,7 +70,7 @@ impl EglWrapper {
pub fn get_display(
&self,
display: Option<ffi::EGLNativeDisplayType>,
) -> Fallible<ffi::types::EGLDisplay> {
) -> anyhow::Result<ffi::types::EGLDisplay> {
let display = unsafe { self.egl.GetDisplay(display.unwrap_or(ffi::DEFAULT_DISPLAY)) };
if display.is_null() {
Err(self.error("egl GetDisplay"))
@ -79,7 +79,7 @@ impl EglWrapper {
}
}
pub fn error(&self, context: &str) -> failure::Error {
pub fn error(&self, context: &str) -> Error {
let label = match unsafe { self.egl.GetError() } as u32 {
ffi::NOT_INITIALIZED => "NOT_INITIALIZED".into(),
ffi::BAD_ACCESS => "BAD_ACCESS".into(),
@ -97,13 +97,13 @@ impl EglWrapper {
ffi::SUCCESS => "Failed but with error code: SUCCESS".into(),
err => format!("EGL Error code: {}", err),
};
failure::format_err!("{}: {}", context, label)
anyhow!("{}: {}", context, label)
}
pub fn initialize_and_get_version(
&self,
display: ffi::types::EGLDisplay,
) -> Fallible<(ffi::EGLint, ffi::EGLint)> {
) -> anyhow::Result<(ffi::EGLint, ffi::EGLint)> {
let mut major = 0;
let mut minor = 0;
unsafe {
@ -119,8 +119,8 @@ impl EglWrapper {
&self,
display: ffi::types::EGLDisplay,
attributes: &[u32],
) -> Fallible<Vec<ffi::types::EGLConfig>> {
failure::ensure!(
) -> anyhow::Result<Vec<ffi::types::EGLConfig>> {
ensure!(
!attributes.is_empty() && attributes[attributes.len() - 1] == ffi::NONE,
"attributes list must be terminated with ffi::NONE"
);
@ -159,7 +159,7 @@ impl EglWrapper {
display: ffi::types::EGLDisplay,
config: ffi::types::EGLConfig,
window: ffi::EGLNativeWindowType,
) -> Fallible<ffi::types::EGLSurface> {
) -> anyhow::Result<ffi::types::EGLSurface> {
let surface = unsafe {
self.egl
.CreateWindowSurface(display, config, window, std::ptr::null())
@ -177,8 +177,8 @@ impl EglWrapper {
config: ffi::types::EGLConfig,
share_context: ffi::types::EGLContext,
attributes: &[u32],
) -> Fallible<ffi::types::EGLConfig> {
failure::ensure!(
) -> anyhow::Result<ffi::types::EGLConfig> {
ensure!(
!attributes.is_empty() && attributes[attributes.len() - 1] == ffi::NONE,
"attributes list must be terminated with ffi::NONE"
);
@ -199,7 +199,9 @@ impl EglWrapper {
}
impl GlState {
fn with_egl_lib<F: FnMut(EglWrapper) -> Fallible<Self>>(mut func: F) -> Fallible<Self> {
fn with_egl_lib<F: FnMut(EglWrapper) -> anyhow::Result<Self>>(
mut func: F,
) -> anyhow::Result<Self> {
let paths = [
// While EGL is cross platform, it isn't available on macOS nor is it
// available on my nvidia based system
@ -230,14 +232,14 @@ impl GlState {
}
}
}
failure::bail!("EGL library not found")
bail!("EGL library not found")
}
#[cfg(all(unix, feature = "wayland", not(target_os = "macos")))]
pub fn create_wayland(
display: Option<ffi::EGLNativeDisplayType>,
wegl_surface: &wayland_client::egl::WlEglSurface,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
Self::with_egl_lib(move |egl| {
let egl_display = egl.get_display(display)?;
@ -269,7 +271,7 @@ impl GlState {
let first_config = *configs
.first()
.ok_or_else(|| failure::err_msg("no compatible EGL configuration was found"))?;
.ok_or_else(|| anyhow!("no compatible EGL configuration was found"))?;
let window = wegl_surface.ptr();
let surface = egl.create_window_surface(egl_display, first_config, window)?;
@ -293,7 +295,7 @@ impl GlState {
pub fn create(
display: Option<ffi::EGLNativeDisplayType>,
window: ffi::EGLNativeWindowType,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
Self::with_egl_lib(|egl| {
let egl_display = egl.get_display(display)?;
@ -325,7 +327,7 @@ impl GlState {
let first_config = *configs
.first()
.ok_or_else(|| failure::err_msg("no compatible EGL configuration was found"))?;
.ok_or_else(|| anyhow!("no compatible EGL configuration was found"))?;
let surface = egl.create_window_surface(egl_display, first_config, window)?;

View File

@ -195,7 +195,7 @@ pub trait WindowOps {
/// The `Any` that is passed in corresponds to the WindowCallbacks
/// impl you passed to `new_window`, pre-converted to Any so that
/// you can `downcast_ref` or `downcast_mut` it and operate on it.
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> failure::Fallible<R>>(
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> anyhow::Result<R>>(
&self,
func: F,
) -> promise::Future<R>
@ -211,8 +211,8 @@ pub trait WindowOps {
+ Fn(
&mut dyn Any,
&dyn WindowOps,
failure::Fallible<std::rc::Rc<glium::backend::Context>>,
) -> failure::Fallible<R>,
anyhow::Result<std::rc::Rc<glium::backend::Context>>,
) -> anyhow::Result<R>,
>(
&self,
func: F,

View File

@ -9,7 +9,6 @@ use cocoa::appkit::{NSApp, NSApplication, NSApplicationActivationPolicyRegular};
use cocoa::base::{id, nil};
use core_foundation::date::CFAbsoluteTimeGetCurrent;
use core_foundation::runloop::*;
use failure::Fallible;
use objc::*;
use promise::BasicExecutor;
use std::cell::RefCell;
@ -25,7 +24,7 @@ pub struct Connection {
}
impl Connection {
pub(crate) fn create_new() -> Fallible<Self> {
pub(crate) fn create_new() -> anyhow::Result<Self> {
// Ensure that the SPAWN_QUEUE is created; it will have nothing
// to run right now.
SPAWN_QUEUE.run();
@ -52,7 +51,10 @@ impl Connection {
self.windows.borrow().get(&window_id).map(Rc::clone)
}
pub(crate) fn with_window_inner<R, F: FnMut(&mut WindowInner) -> Fallible<R> + Send + 'static>(
pub(crate) fn with_window_inner<
R,
F: FnMut(&mut WindowInner) -> anyhow::Result<R> + Send + 'static,
>(
window_id: usize,
mut f: F,
) -> promise::Future<R>
@ -87,7 +89,7 @@ impl ConnectionOps for Connection {
}
}
fn run_message_loop(&self) -> Fallible<()> {
fn run_message_loop(&self) -> anyhow::Result<()> {
unsafe {
self.ns_app.run();
}

View File

@ -10,6 +10,7 @@ use crate::{
MouseCursor, MouseEvent, MouseEventKind, MousePress, Operator, PaintContext, Point, Rect,
ScreenPoint, Size, WindowCallbacks, WindowOps, WindowOpsMut,
};
use anyhow::{bail, ensure, Context};
use cocoa::appkit::{
NSApplicationActivateIgnoringOtherApps, NSBackingStoreBuffered, NSEvent, NSEventModifierFlags,
NSRunningApplication, NSScreen, NSView, NSViewHeightSizable, NSViewWidthSizable, NSWindow,
@ -18,7 +19,6 @@ use cocoa::appkit::{
use cocoa::base::*;
use cocoa::foundation::{NSArray, NSNotFound, NSPoint, NSRect, NSSize, NSUInteger};
use core_graphics::image::CGImageRef;
use failure::Fallible;
use objc::declare::ClassDecl;
use objc::rc::{StrongPtr, WeakPtr};
use objc::runtime::{Class, Object, Protocol, Sel};
@ -87,7 +87,7 @@ mod opengl {
}
impl GlContextPair {
pub fn create(view: id) -> Fallible<Self> {
pub fn create(view: id) -> anyhow::Result<Self> {
let backend = Rc::new(GlState::create(view)?);
let context = unsafe {
@ -112,7 +112,7 @@ mod opengl {
}
impl GlState {
pub fn create(view: id) -> Fallible<Self> {
pub fn create(view: id) -> anyhow::Result<Self> {
let pixel_format = unsafe {
StrongPtr::new(NSOpenGLPixelFormat::alloc(nil).initWithAttributes_(&[
appkit::NSOpenGLPFAOpenGLProfile as u32,
@ -132,7 +132,7 @@ mod opengl {
0,
]))
};
failure::ensure!(
ensure!(
!pixel_format.is_null(),
"failed to create NSOpenGLPixelFormat"
);
@ -148,7 +148,7 @@ mod opengl {
NSOpenGLContext::alloc(nil).initWithFormat_shareContext_(*pixel_format, nil),
)
};
failure::ensure!(!gl_context.is_null(), "failed to create NSOpenGLContext");
ensure!(!gl_context.is_null(), "failed to create NSOpenGLContext");
unsafe {
gl_context.setView_(view);
}
@ -264,7 +264,7 @@ impl Window {
width: usize,
height: usize,
callbacks: Box<dyn WindowCallbacks>,
) -> Fallible<Window> {
) -> anyhow::Result<Window> {
unsafe {
let style_mask = NSWindowStyleMask::NSTitledWindowMask
| NSWindowStyleMask::NSClosableWindowMask
@ -407,7 +407,7 @@ impl WindowOps for Window {
})
}
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> Fallible<R>>(
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> anyhow::Result<R>>(
&self,
func: F,
) -> promise::Future<R>
@ -421,7 +421,7 @@ impl WindowOps for Window {
if let Some(window_view) = WindowView::get_this(unsafe { &**inner.view }) {
func(window_view.inner.borrow_mut().callbacks.as_any(), &window)
} else {
failure::bail!("apply: window is invalid");
bail!("apply: window is invalid");
}
})
}
@ -434,8 +434,8 @@ impl WindowOps for Window {
+ Fn(
&mut dyn Any,
&dyn WindowOps,
failure::Fallible<std::rc::Rc<glium::backend::Context>>,
) -> failure::Fallible<R>,
anyhow::Result<std::rc::Rc<glium::backend::Context>>,
) -> anyhow::Result<R>,
>(
&self,
func: F,
@ -459,7 +459,7 @@ impl WindowOps for Window {
glium_context.map(|pair| pair.context),
)
} else {
failure::bail!("enable_opengl: window is invalid");
bail!("enable_opengl: window is invalid");
}
})
}
@ -469,7 +469,7 @@ impl WindowOps for Window {
Future::result(
clipboard::ClipboardContext::new()
.and_then(|mut ctx| ctx.get_contents())
.map_err(|e| failure::format_err!("Failed to get clipboard: {}", e)),
.with_context(|| format!("Failed to get clipboard: {}", e)),
)
}
@ -478,7 +478,7 @@ impl WindowOps for Window {
Future::result(
clipboard::ClipboardContext::new()
.and_then(|mut ctx| ctx.set_contents(text))
.map_err(|e| failure::format_err!("Failed to set clipboard: {}", e)),
.with_context(|| format!("Failed to set clipboard: {}", e)),
)
}
}
@ -1233,7 +1233,7 @@ impl WindowView {
}
}
fn alloc(inner: &Rc<RefCell<Inner>>, buffer: Image) -> Fallible<StrongPtr> {
fn alloc(inner: &Rc<RefCell<Inner>>, buffer: Image) -> anyhow::Result<StrongPtr> {
let cls = Self::get_class();
let view_id: StrongPtr = unsafe { StrongPtr::new(msg_send![cls, new]) };

View File

@ -7,7 +7,7 @@ use crate::spawn::*;
use crate::tasks::{Task, Tasks};
use crate::timerlist::{TimerEntry, TimerList};
use crate::Connection;
use failure::Fallible;
use anyhow::{bail, Context};
use mio::unix::EventedFd;
use mio::{Evented, Events, Poll, PollOpt, Ready, Token};
use promise::BasicExecutor;
@ -71,7 +71,7 @@ impl Evented for WaylandConnection {
}
impl WaylandConnection {
pub fn create_new() -> Fallible<Self> {
pub fn create_new() -> anyhow::Result<Self> {
let (display, mut event_q) = Display::connect_to_env()?;
let environment = Environment::from_display(&*display, &mut event_q)?;
@ -87,7 +87,7 @@ impl WaylandConnection {
(),
)
})
.map_err(|_| failure::format_err!("Failed to create seat"))?;
.with_context(|| format!("Failed to create seat"))?;
let keyboard = KeyboardDispatcher::register(&seat)?;
let pointer = PointerDispatcher::register(
@ -125,10 +125,10 @@ impl WaylandConnection {
LowPriSpawnQueueExecutor {}
}
fn flush(&self) -> Fallible<()> {
fn flush(&self) -> anyhow::Result<()> {
if let Err(e) = self.display.borrow_mut().flush() {
if e.kind() != ::std::io::ErrorKind::WouldBlock {
failure::bail!("Error while flushing display: {}", e);
bail!("Error while flushing display: {}", e);
}
}
Ok(())
@ -136,13 +136,13 @@ impl WaylandConnection {
fn do_paint(&self) {}
fn process_queued_events(&self) -> Fallible<()> {
fn process_queued_events(&self) -> anyhow::Result<()> {
{
let mut event_q = self.event_q.borrow_mut();
if let Some(guard) = event_q.prepare_read() {
if let Err(e) = guard.read_events() {
if e.kind() != ::std::io::ErrorKind::WouldBlock {
failure::bail!("Error while reading events: {}", e);
bail!("Error while reading events: {}", e);
}
}
}
@ -158,7 +158,7 @@ impl WaylandConnection {
pub(crate) fn with_window_inner<
R,
F: FnMut(&mut WaylandWindowInner) -> Fallible<R> + Send + 'static,
F: FnMut(&mut WaylandWindowInner) -> anyhow::Result<R> + Send + 'static,
>(
window: usize,
mut f: F,
@ -194,7 +194,7 @@ impl ConnectionOps for WaylandConnection {
*self.should_terminate.borrow_mut() = true;
}
fn run_message_loop(&self) -> Fallible<()> {
fn run_message_loop(&self) -> anyhow::Result<()> {
println!("run_message_loop:flush");
self.flush()?;
@ -260,7 +260,7 @@ impl ConnectionOps for WaylandConnection {
}
Err(err) => {
failure::bail!("polling for events: {:?}", err);
bail!("polling for events: {:?}", err);
}
}
}

View File

@ -1,4 +1,4 @@
use failure::Fallible;
use anyhow::{anyhow, Error};
use filedescriptor::{FileDescriptor, Pipe};
use smithay_client_toolkit as toolkit;
use std::os::unix::io::AsRawFd;
@ -34,12 +34,12 @@ impl CopyAndPaste {
}
}
pub fn get_clipboard_data(&mut self) -> Fallible<FileDescriptor> {
pub fn get_clipboard_data(&mut self) -> anyhow::Result<FileDescriptor> {
let offer = self
.data_offer
.as_ref()
.ok_or_else(|| failure::err_msg("no data offer"))?;
let pipe = Pipe::new()?;
.ok_or_else(|| anyhow!("no data offer"))?;
let pipe = Pipe::new().map_err(Error::msg)?;
offer.receive(TEXT_MIME_TYPE.to_string(), pipe.write.as_raw_fd());
Ok(pipe.read)
}

View File

@ -1,6 +1,6 @@
use crate::input::*;
use crate::os::wayland::connection::WaylandConnection;
use failure::Fallible;
use anyhow::anyhow;
use smithay_client_toolkit as toolkit;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
@ -64,7 +64,7 @@ pub struct KeyboardDispatcher {
}
impl KeyboardDispatcher {
pub fn register(seat: &WlSeat) -> Fallible<Self> {
pub fn register(seat: &WlSeat) -> anyhow::Result<Self> {
let inner = Arc::new(Mutex::new(Inner::default()));
map_keyboard_auto_with_repeat(
@ -86,7 +86,7 @@ impl KeyboardDispatcher {
}
},
)
.map_err(|_| failure::format_err!("Failed to configure keyboard callback"))?;
.map_err(|e| anyhow!("Failed to configure keyboard callback: {:?}", e))?;
Ok(Self { inner })
}

View File

@ -1,7 +1,7 @@
use super::copy_and_paste::*;
use crate::input::*;
use crate::os::wayland::connection::WaylandConnection;
use failure::Fallible;
use anyhow::anyhow;
use smithay_client_toolkit as toolkit;
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
@ -217,7 +217,7 @@ impl PointerDispatcher {
compositor: WlCompositor,
shm: &WlShm,
dev_mgr: &WlDataDeviceManager,
) -> Fallible<Self> {
) -> anyhow::Result<Self> {
let inner = Arc::new(Mutex::new(Inner::default()));
let pointer = seat
.get_pointer({
@ -234,7 +234,7 @@ impl PointerDispatcher {
)
}
})
.map_err(|_| failure::format_err!("Failed to configure pointer callback"))?;
.map_err(|()| anyhow!("Failed to configure pointer callback"))?;
let themer = AutoThemer::init(None, compositor, shm);
let auto_pointer = themer.theme_pointer(pointer);
@ -254,7 +254,7 @@ impl PointerDispatcher {
)
}
})
.map_err(|_| failure::format_err!("Failed to configure data_device"))?;
.map_err(|()| anyhow!("Failed to configure data_device"))?;
Ok(Self {
inner,

View File

@ -11,7 +11,7 @@ use crate::{
Connection, Dimensions, MouseCursor, Operator, PaintContext, Point, Rect, ScreenPoint, Window,
WindowCallbacks, WindowOps, WindowOpsMut,
};
use failure::Fallible;
use anyhow::{anyhow, bail, Context};
use filedescriptor::FileDescriptor;
use promise::{Future, Promise};
use smithay_client_toolkit as toolkit;
@ -155,10 +155,10 @@ impl WaylandWindow {
width: usize,
height: usize,
callbacks: Box<dyn WindowCallbacks>,
) -> Fallible<Window> {
) -> anyhow::Result<Window> {
let conn = WaylandConnection::get()
.ok_or_else(|| {
failure::err_msg(
anyhow!(
"new_window must be called on the gui thread after Connection::init has succeeded",
)
})?
@ -195,7 +195,7 @@ impl WaylandWindow {
}
},
)
.map_err(|e| failure::format_err!("Failed to create window: {}", e))?;
.context("Failed to create window")?;
window.set_app_id(class_name.to_string());
window.set_decorate(true);
@ -466,7 +466,7 @@ impl WaylandWindowInner {
}
}
fn do_paint(&mut self) -> Fallible<()> {
fn do_paint(&mut self) -> anyhow::Result<()> {
#[cfg(feature = "opengl")]
{
if let Some(gl_context) = self.gl_state.as_ref() {
@ -651,7 +651,7 @@ impl WindowOps for WaylandWindow {
})
}
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> Fallible<R>>(
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> anyhow::Result<R>>(
&self,
func: F,
) -> promise::Future<R>
@ -673,8 +673,8 @@ impl WindowOps for WaylandWindow {
+ Fn(
&mut dyn Any,
&dyn WindowOps,
failure::Fallible<std::rc::Rc<glium::backend::Context>>,
) -> failure::Fallible<R>,
anyhow::Result<std::rc::Rc<glium::backend::Context>>,
) -> anyhow::Result<R>,
>(
&self,
func: F,
@ -689,7 +689,7 @@ impl WindowOps for WaylandWindow {
let mut wegl_surface = None;
let gl_state = if !egl_is_available() {
Err(failure::err_msg("!egl_is_available"))
Err(anyhow!("!egl_is_available"))
} else {
wegl_surface = Some(WlEglSurface::new(
&inner.surface,
@ -737,7 +737,7 @@ impl WindowOps for WaylandWindow {
}
Err(e) => {
log::error!("while reading clipboard: {}", e);
promise.err(failure::format_err!("{}", e));
promise.err(anyhow!("{}", e));
}
};
});
@ -768,7 +768,7 @@ impl WindowOps for WaylandWindow {
(),
)
})
.map_err(|_| failure::format_err!("failed to create data source"))?;
.map_err(|()| anyhow!("failed to create data source"))?;
source.offer(TEXT_MIME_TYPE.to_string());
inner.copy_and_paste.lock().unwrap().set_selection(source);
@ -777,7 +777,7 @@ impl WindowOps for WaylandWindow {
}
}
fn write_pipe_with_timeout(mut file: FileDescriptor, data: &[u8]) -> Fallible<()> {
fn write_pipe_with_timeout(mut file: FileDescriptor, data: &[u8]) -> anyhow::Result<()> {
let on: libc::c_int = 1;
unsafe {
libc::ioctl(file.as_raw_fd(), libc::FIONBIO, &on);
@ -794,22 +794,22 @@ fn write_pipe_with_timeout(mut file: FileDescriptor, data: &[u8]) -> Fallible<()
if unsafe { libc::poll(&mut pfd, 1, 3000) == 1 } {
match file.write(buf) {
Ok(size) if size == 0 => {
failure::bail!("zero byte write");
bail!("zero byte write");
}
Ok(size) => {
buf = &buf[size..];
}
Err(e) => failure::bail!("error writing to pipe: {}", e),
Err(e) => bail!("error writing to pipe: {}", e),
}
} else {
failure::bail!("timed out writing to pipe");
bail!("timed out writing to pipe");
}
}
Ok(())
}
fn read_pipe_with_timeout(mut file: FileDescriptor) -> Fallible<String> {
fn read_pipe_with_timeout(mut file: FileDescriptor) -> anyhow::Result<String> {
let mut result = Vec::new();
let on: libc::c_int = 1;
@ -833,10 +833,10 @@ fn read_pipe_with_timeout(mut file: FileDescriptor) -> Fallible<String> {
Ok(size) => {
result.extend_from_slice(&buf[..size]);
}
Err(e) => failure::bail!("error reading from pipe: {}", e),
Err(e) => bail!("error reading from pipe: {}", e),
}
} else {
failure::bail!("timed out reading from pipe");
bail!("timed out reading from pipe");
}
}

View File

@ -3,7 +3,6 @@ use super::{HWindow, WindowInner};
use crate::connection::ConnectionOps;
use crate::spawn::*;
use crate::tasks::{Task, Tasks};
use failure::Fallible;
use promise::BasicExecutor;
use std::cell::RefCell;
use std::collections::HashMap;
@ -31,7 +30,7 @@ impl ConnectionOps for Connection {
}
}
fn run_message_loop(&self) -> Fallible<()> {
fn run_message_loop(&self) -> anyhow::Result<()> {
let mut msg: MSG = unsafe { std::mem::zeroed() };
loop {
SPAWN_QUEUE.run();
@ -107,7 +106,7 @@ impl ConnectionOps for Connection {
}
impl Connection {
pub(crate) fn create_new() -> Fallible<Self> {
pub(crate) fn create_new() -> anyhow::Result<Self> {
let event_handle = SPAWN_QUEUE.event_handle.0;
Ok(Self {
event_handle,
@ -135,7 +134,10 @@ impl Connection {
self.windows.borrow().get(&handle).map(Rc::clone)
}
pub(crate) fn with_window_inner<R, F: FnMut(&mut WindowInner) -> Fallible<R> + Send + 'static>(
pub(crate) fn with_window_inner<
R,
F: FnMut(&mut WindowInner) -> anyhow::Result<R> + Send + 'static,
>(
window: HWindow,
mut f: F,
) -> promise::Future<R>

View File

@ -1,4 +1,3 @@
use failure::Fallible;
use std::io::Error as IoError;
use std::ptr::{null, null_mut};
use winapi::um::handleapi::CloseHandle;
@ -18,7 +17,7 @@ impl Drop for EventHandle {
}
impl EventHandle {
pub fn new_manual_reset() -> Fallible<Self> {
pub fn new_manual_reset() -> anyhow::Result<Self> {
let handle = unsafe { CreateEventW(null_mut(), 1, 0, null()) };
if handle.is_null() {
return Err(IoError::last_os_error().into());

View File

@ -1,5 +1,5 @@
use crate::bitmaps::BitmapImage;
use failure::Fallible;
use anyhow::bail;
use std::io::Error as IoError;
use winapi::shared::windef::*;
use winapi::um::wingdi::*;
@ -57,11 +57,11 @@ impl GdiBitmap {
}
}
pub fn new_compatible(width: usize, height: usize, hdc: HDC) -> Fallible<Self> {
pub fn new_compatible(width: usize, height: usize, hdc: HDC) -> anyhow::Result<Self> {
let hdc = unsafe { CreateCompatibleDC(hdc) };
if hdc.is_null() {
let err = IoError::last_os_error();
failure::bail!("CreateCompatibleDC: {}", err);
bail!("CreateCompatibleDC: {}", err);
}
let mut data = std::ptr::null_mut();
@ -102,7 +102,7 @@ impl GdiBitmap {
if hbitmap.is_null() {
let err = IoError::last_os_error();
failure::bail!("CreateDIBSection: {}", err);
bail!("CreateDIBSection: {}", err);
}
unsafe {

View File

@ -1,6 +1,5 @@
#![cfg(feature = "opengl")]
use failure::Fallible;
use std::os::raw::c_void;
use winapi::shared::windef::*;
use winapi::um::wingdi::*;
@ -19,7 +18,7 @@ type GetProcAddressFunc =
unsafe extern "system" fn(*const std::os::raw::c_char) -> *const std::os::raw::c_void;
impl WglWrapper {
pub fn create() -> Fallible<Self> {
pub fn create() -> anyhow::Result<Self> {
let lib = libloading::Library::new("opengl32.dll")?;
let get_proc_address: libloading::Symbol<GetProcAddressFunc> =
@ -42,7 +41,7 @@ pub struct GlState {
}
impl GlState {
pub fn create(window: HWND) -> Fallible<Self> {
pub fn create(window: HWND) -> anyhow::Result<Self> {
let wgl = WglWrapper::create()?;
let hdc = unsafe { GetDC(window) };

View File

@ -8,7 +8,6 @@ use crate::{
MouseEventKind, MousePress, Operator, PaintContext, Point, Rect, ScreenPoint, WindowCallbacks,
WindowOps, WindowOpsMut,
};
use failure::Fallible;
use promise::Future;
use std::any::Any;
use std::cell::RefCell;
@ -108,7 +107,7 @@ impl Window {
width: usize,
height: usize,
lparam: *const RefCell<WindowInner>,
) -> Fallible<HWND> {
) -> anyhow::Result<HWND> {
// Jamming this in here; it should really live in the application manifest,
// but having it here means that we don't have to create a manifest
unsafe {
@ -164,7 +163,7 @@ impl Window {
if hwnd.is_null() {
let err = IoError::last_os_error();
failure::bail!("CreateWindowExW: {}", err);
bail!("CreateWindowExW: {}", err);
}
Ok(hwnd)
@ -176,7 +175,7 @@ impl Window {
width: usize,
height: usize,
callbacks: Box<dyn WindowCallbacks>,
) -> Fallible<Window> {
) -> anyhow::Result<Window> {
let inner = Rc::new(RefCell::new(WindowInner {
hwnd: HWindow(null_mut()),
callbacks: RefCell::new(callbacks),
@ -368,7 +367,7 @@ impl WindowOps for Window {
})
}
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> Fallible<R>>(
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> anyhow::Result<R>>(
&self,
func: F,
) -> promise::Future<R>
@ -390,8 +389,8 @@ impl WindowOps for Window {
+ Fn(
&mut dyn Any,
&dyn WindowOps,
failure::Fallible<std::rc::Rc<glium::backend::Context>>,
) -> failure::Fallible<R>,
anyhow::Result<std::rc::Rc<glium::backend::Context>>,
) -> anyhow::Result<R>,
>(
&self,
func: F,
@ -424,16 +423,12 @@ impl WindowOps for Window {
}
fn get_clipboard(&self) -> Future<String> {
Future::result(
clipboard_win::get_clipboard_string()
.map_err(|e| failure::format_err!("Error getting clipboard: {}", e)),
)
Future::result(clipboard_win::get_clipboard_string().context("Error getting clipboard: {}"))
}
fn set_clipboard(&self, text: String) -> Future<()> {
Future::result(
clipboard_win::set_clipboard_string(&text)
.map_err(|e| failure::format_err!("Error setting clipboard: {}", e)),
clipboard_win::set_clipboard_string(&text).context("Error setting clipboard"),
)
}
}

View File

@ -1,6 +1,6 @@
use super::*;
use crate::bitmaps::*;
use failure::{bail, Fallible};
use anyhow::bail;
use std::rc::Rc;
/// The X protocol allows referencing a number of drawable
@ -106,7 +106,7 @@ struct ShmData {
impl ShmId {
/// Create a new private shared memory segment of the specified size
fn new(size: usize) -> Fallible<ShmId> {
fn new(size: usize) -> anyhow::Result<ShmId> {
let id = unsafe { libc::shmget(libc::IPC_PRIVATE, size, libc::IPC_CREAT | 0o600) };
if id == -1 {
bail!(
@ -119,7 +119,7 @@ impl ShmId {
}
/// Attach the segment to our address space
fn attach(&self) -> Fallible<ShmData> {
fn attach(&self) -> anyhow::Result<ShmData> {
let data = unsafe { libc::shmat(self.id, std::ptr::null(), 0) };
if data as usize == !0 {
bail!(
@ -168,7 +168,7 @@ impl ShmImage {
drawable: xcb::xproto::Drawable,
width: usize,
height: usize,
) -> Fallible<ShmImage> {
) -> anyhow::Result<ShmImage> {
if !conn.shm_available {
bail!("SHM not available");
}

View File

@ -5,7 +5,7 @@ use crate::os::Connection;
use crate::spawn::*;
use crate::tasks::{Task, Tasks};
use crate::timerlist::{TimerEntry, TimerList};
use failure::Fallible;
use anyhow::{anyhow, bail};
use mio::unix::EventedFd;
use mio::{Evented, Events, Poll, PollOpt, Ready, Token};
use promise::BasicExecutor;
@ -173,7 +173,7 @@ impl ConnectionOps for XConnection {
*self.should_terminate.borrow_mut() = true;
}
fn run_message_loop(&self) -> Fallible<()> {
fn run_message_loop(&self) -> anyhow::Result<()> {
self.conn.flush();
const TOK_XCB: usize = 0xffff_fffc;
@ -238,7 +238,7 @@ impl ConnectionOps for XConnection {
}
Err(err) => {
failure::bail!("polling for events: {:?}", err);
bail!("polling for events: {:?}", err);
}
}
}
@ -256,12 +256,12 @@ impl ConnectionOps for XConnection {
}
impl XConnection {
fn process_queued_xcb(&self) -> Fallible<()> {
fn process_queued_xcb(&self) -> anyhow::Result<()> {
match self.conn.poll_for_event() {
None => match self.conn.has_error() {
Ok(_) => (),
Err(err) => {
failure::bail!("X11 connection is broken: {:?}", err);
bail!("X11 connection is broken: {:?}", err);
}
},
Some(event) => {
@ -281,7 +281,7 @@ impl XConnection {
}
}
fn process_xcb_event(&self, event: &xcb::GenericEvent) -> Fallible<()> {
fn process_xcb_event(&self, event: &xcb::GenericEvent) -> anyhow::Result<()> {
if let Some(window_id) = window_id_from_event(event) {
self.process_window_event(window_id, event)?;
} else {
@ -305,7 +305,7 @@ impl XConnection {
&self,
window_id: xcb::xproto::Window,
event: &xcb::GenericEvent,
) -> Fallible<()> {
) -> anyhow::Result<()> {
if let Some(window) = self.window_by_id(window_id) {
let mut inner = window.lock().unwrap();
inner.dispatch_event(event)?;
@ -313,15 +313,15 @@ impl XConnection {
Ok(())
}
pub(crate) fn create_new() -> Fallible<XConnection> {
pub(crate) fn create_new() -> anyhow::Result<XConnection> {
let display = unsafe { x11::xlib::XOpenDisplay(std::ptr::null()) };
if display.is_null() {
failure::bail!("failed to open display");
bail!("failed to open display");
}
let screen_num = unsafe { x11::xlib::XDefaultScreen(display) };
let conn = unsafe { xcb::Connection::from_raw_conn(XGetXCBConnection(display)) };
let conn = xcb_util::ewmh::Connection::connect(conn)
.map_err(|_| failure::err_msg("failed to init ewmh"))?;
.map_err(|_| anyhow!("failed to init ewmh"))?;
unsafe { XSetEventQueueOwner(display, 1) };
let atom_protocols = xcb::intern_atom(&conn, false, "WM_PROTOCOLS")
@ -352,7 +352,7 @@ impl XConnection {
.get_setup()
.roots()
.nth(screen_num as usize)
.ok_or_else(|| failure::err_msg("no screen?"))?;
.ok_or_else(|| anyhow!("no screen?"))?;
let visual = screen
.allowed_depths()
@ -360,7 +360,7 @@ impl XConnection {
.flat_map(|depth| depth.visuals())
.filter(|vis| vis.class() == xcb::xproto::VISUAL_CLASS_TRUE_COLOR as _)
.nth(0)
.ok_or_else(|| failure::err_msg("did not find 24-bit visual"))?;
.ok_or_else(|| anyhow!("did not find 24-bit visual"))?;
eprintln!(
"picked visual {:x}, screen root visual is {:x}",
visual.visual_id(),
@ -432,7 +432,7 @@ impl XConnection {
pub(crate) fn with_window_inner<
R,
F: FnMut(&mut XWindowInner) -> Fallible<R> + Send + 'static,
F: FnMut(&mut XWindowInner) -> anyhow::Result<R> + Send + 'static,
>(
window: xcb::xproto::Window,
mut f: F,

View File

@ -1,6 +1,6 @@
use crate::os::xkeysyms::keysym_to_keycode;
use crate::{KeyCode, Modifiers};
use failure::{ensure, format_err, Fallible};
use anyhow::{anyhow, ensure};
use libc;
use std::cell::RefCell;
use std::ffi::CStr;
@ -17,13 +17,13 @@ pub struct Keyboard {
}
impl Keyboard {
pub fn new(connection: &xcb::Connection) -> Fallible<(Keyboard, u8)> {
pub fn new(connection: &xcb::Connection) -> anyhow::Result<(Keyboard, u8)> {
connection.prefetch_extension_data(xcb::xkb::id());
let first_ev = connection
.get_extension_data(xcb::xkb::id())
.map(|r| r.first_event())
.ok_or_else(|| format_err!("could not get xkb extension data"))?;
.ok_or_else(|| anyhow!("could not get xkb extension data"))?;
{
let cookie = xcb::xkb::use_extension(
@ -60,7 +60,7 @@ impl Keyboard {
locale.to_str()?,
xkb::compose::COMPILE_NO_FLAGS,
)
.map_err(|()| format_err!("Failed to acquire compose table from locale"))?;
.map_err(|_| anyhow!("Failed to acquire compose table from locale"))?;
let compose_state = xkb::compose::State::new(&table, xkb::compose::STATE_NO_FLAGS);
{
@ -185,7 +185,7 @@ impl Keyboard {
&self,
connection: &xcb::Connection,
event: &xcb::GenericEvent,
) -> Fallible<()> {
) -> anyhow::Result<()> {
let xkb_ev: &XkbGenericEvent = unsafe { xcb::cast_event(&event) };
if xkb_ev.device_id() == self.get_device_id() as u8 {
@ -213,7 +213,7 @@ impl Keyboard {
);
}
pub fn update_keymap(&self, connection: &xcb::Connection) -> Fallible<()> {
pub fn update_keymap(&self, connection: &xcb::Connection) -> anyhow::Result<()> {
let new_keymap = xkb::x11::keymap_new_from_device(
&self.context,
&connection,
@ -238,7 +238,7 @@ impl Keyboard {
}
}
fn query_lc_ctype() -> Fallible<&'static CStr> {
fn query_lc_ctype() -> anyhow::Result<&'static CStr> {
let ptr = unsafe { libc::setlocale(libc::LC_CTYPE, std::ptr::null()) };
ensure!(!ptr.is_null(), "failed to query locale");
unsafe { Ok(CStr::from_ptr(ptr)) }

View File

@ -8,7 +8,7 @@ use crate::{
Operator, PaintContext, Point, Rect, ScreenPoint, Size, WindowCallbacks, WindowOps,
WindowOpsMut,
};
use failure::Fallible;
use anyhow::anyhow;
use promise::{Future, Promise};
use std::any::Any;
use std::collections::VecDeque;
@ -94,7 +94,7 @@ impl<'a> PaintContext for X11GraphicsContext<'a> {
}
impl XWindowInner {
pub fn paint(&mut self) -> Fallible<()> {
pub fn paint(&mut self) -> anyhow::Result<()> {
let window_dimensions =
Rect::from_size(Size::new(self.width as isize, self.height as isize));
@ -206,13 +206,13 @@ impl XWindowInner {
self.expose.push_back(expose);
}
fn do_mouse_event(&mut self, event: &MouseEvent) -> Fallible<()> {
fn do_mouse_event(&mut self, event: &MouseEvent) -> anyhow::Result<()> {
self.callbacks
.mouse_event(&event, &XWindow::from_id(self.window_id));
Ok(())
}
fn set_cursor(&mut self, cursor: Option<MouseCursor>) -> Fallible<()> {
fn set_cursor(&mut self, cursor: Option<MouseCursor>) -> anyhow::Result<()> {
if cursor == self.cursor {
return Ok(());
}
@ -251,7 +251,7 @@ impl XWindowInner {
Ok(())
}
pub fn dispatch_event(&mut self, event: &xcb::GenericEvent) -> Fallible<()> {
pub fn dispatch_event(&mut self, event: &xcb::GenericEvent) -> anyhow::Result<()> {
let r = event.response_type() & 0x7f;
match r {
xcb::EXPOSE => {
@ -411,7 +411,7 @@ impl XWindowInner {
self.conn.flush();
}
fn selection_clear(&mut self) -> Fallible<()> {
fn selection_clear(&mut self) -> anyhow::Result<()> {
self.copy_and_paste.owned.take();
self.copy_and_paste.request.take();
self.update_selection_owner();
@ -420,7 +420,7 @@ impl XWindowInner {
/// A selection request is made to us after we've announced that we own the selection
/// and when another client wants to copy it.
fn selection_request(&mut self, request: &xcb::SelectionRequestEvent) -> Fallible<()> {
fn selection_request(&mut self, request: &xcb::SelectionRequestEvent) -> anyhow::Result<()> {
log::trace!(
"SEL: time={} owner={} requestor={} selection={} target={} property={}",
request.time(),
@ -500,7 +500,7 @@ impl XWindowInner {
Ok(())
}
fn selection_notify(&mut self, selection: &xcb::SelectionNotifyEvent) -> Fallible<()> {
fn selection_notify(&mut self, selection: &xcb::SelectionNotifyEvent) -> anyhow::Result<()> {
log::trace!(
"SELECTION_NOTIFY received selection={} (prim={} clip={}) target={} property={}",
selection.selection(),
@ -540,7 +540,7 @@ impl XWindowInner {
}
#[allow(dead_code, clippy::identity_op)]
fn disable_decorations(&mut self) -> Fallible<()> {
fn disable_decorations(&mut self) -> anyhow::Result<()> {
// Set the motif hints to disable decorations.
// See https://stackoverflow.com/a/1909708
#[repr(C)]
@ -605,10 +605,10 @@ impl XWindow {
width: usize,
height: usize,
callbacks: Box<dyn WindowCallbacks>,
) -> Fallible<Window> {
) -> anyhow::Result<Window> {
let conn = Connection::get()
.ok_or_else(|| {
failure::err_msg(
anyhow!(
"new_window must be called on the gui thread after Connection::init has succeeded",
)
})?
@ -620,7 +620,7 @@ impl XWindow {
let screen = setup
.roots()
.nth(conn.screen_num() as usize)
.ok_or_else(|| failure::err_msg("no screen?"))?;
.ok_or_else(|| anyhow!("no screen?"))?;
window_id = conn.conn().generate_id();
@ -834,7 +834,7 @@ impl WindowOps for XWindow {
})
}
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> Fallible<R>>(
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> anyhow::Result<R>>(
&self,
func: F,
) -> promise::Future<R>
@ -856,8 +856,8 @@ impl WindowOps for XWindow {
+ Fn(
&mut dyn Any,
&dyn WindowOps,
failure::Fallible<std::rc::Rc<glium::backend::Context>>,
) -> failure::Fallible<R>,
anyhow::Result<std::rc::Rc<glium::backend::Context>>,
) -> anyhow::Result<R>,
>(
&self,
func: F,

View File

@ -9,7 +9,6 @@ use crate::os::x11::connection::XConnection;
use crate::os::x11::window::XWindow;
use crate::spawn::*;
use crate::{MouseCursor, ScreenPoint, WindowCallbacks, WindowOps};
use failure::Fallible;
use promise::*;
use std::any::Any;
use std::rc::Rc;
@ -41,7 +40,7 @@ impl Connection {
ALLOW_WAYLAND.load(Ordering::Acquire)
}
pub(crate) fn create_new() -> Fallible<Connection> {
pub(crate) fn create_new() -> anyhow::Result<Connection> {
#[cfg(feature = "wayland")]
{
if Self::is_wayland_enabled() {
@ -66,7 +65,7 @@ impl Connection {
width: usize,
height: usize,
callbacks: Box<dyn WindowCallbacks>,
) -> Fallible<Window> {
) -> anyhow::Result<Window> {
match self {
Self::X11(_) => XWindow::new_window(class_name, name, width, height, callbacks),
#[cfg(feature = "wayland")]
@ -132,7 +131,7 @@ impl ConnectionOps for Connection {
}
}
fn run_message_loop(&self) -> Fallible<()> {
fn run_message_loop(&self) -> anyhow::Result<()> {
match self {
Self::X11(x) => x.run_message_loop(),
#[cfg(feature = "wayland")]
@ -155,7 +154,7 @@ impl Window {
width: usize,
height: usize,
callbacks: Box<dyn WindowCallbacks>,
) -> Fallible<Window> {
) -> anyhow::Result<Window> {
Connection::get()
.unwrap()
.new_window(class_name, name, width, height, callbacks)
@ -227,7 +226,7 @@ impl WindowOps for Window {
}
}
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> Fallible<R>>(
fn apply<R, F: Send + 'static + Fn(&mut dyn Any, &dyn WindowOps) -> anyhow::Result<R>>(
&self,
func: F,
) -> promise::Future<R>
@ -250,8 +249,8 @@ impl WindowOps for Window {
+ Fn(
&mut dyn Any,
&dyn WindowOps,
failure::Fallible<std::rc::Rc<glium::backend::Context>>,
) -> failure::Fallible<R>,
anyhow::Result<std::rc::Rc<glium::backend::Context>>,
) -> anyhow::Result<R>,
>(
&self,
func: F,

View File

@ -2,7 +2,6 @@
use crate::os::windows::event::EventHandle;
#[cfg(target_os = "macos")]
use core_foundation::runloop::*;
use failure::Fallible;
use promise::{BasicExecutor, SpawnFunc};
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
@ -32,7 +31,7 @@ pub(crate) struct SpawnQueue {
}
impl SpawnQueue {
pub fn new() -> Fallible<Self> {
pub fn new() -> anyhow::Result<Self> {
Self::new_impl()
}
@ -72,7 +71,7 @@ impl SpawnQueue {
#[cfg(windows)]
impl SpawnQueue {
fn new_impl() -> Fallible<Self> {
fn new_impl() -> anyhow::Result<Self> {
let spawned_funcs = Mutex::new(VecDeque::new());
let spawned_funcs_low_pri = Mutex::new(VecDeque::new());
let event_handle = EventHandle::new_manual_reset().expect("EventHandle creation failed");
@ -99,7 +98,7 @@ impl SpawnQueue {
#[cfg(all(unix, not(target_os = "macos")))]
impl SpawnQueue {
fn new_impl() -> Fallible<Self> {
fn new_impl() -> anyhow::Result<Self> {
// On linux we have a slightly sloppy wakeup mechanism;
// we have a non-blocking pipe that we can use to get
// woken up after some number of enqueues. We don't
@ -110,7 +109,7 @@ impl SpawnQueue {
// We can't affort to use a blocking pipe for the wakeup
// because the write needs to hold a mutex and that
// can block reads as well as other writers.
let pipe = Pipe::new()?;
let pipe = Pipe::new().map_err(anyhow::Error::msg)?;
let on = 1;
unsafe {
libc::ioctl(pipe.write.as_raw_fd(), libc::FIONBIO, &on);
@ -183,7 +182,7 @@ impl Evented for SpawnQueue {
#[cfg(target_os = "macos")]
impl SpawnQueue {
fn new_impl() -> Fallible<Self> {
fn new_impl() -> anyhow::Result<Self> {
let spawned_funcs = Mutex::new(VecDeque::new());
let spawned_funcs_low_pri = Mutex::new(VecDeque::new());