💅 use TryFrom<Object> bounds instead of FromObject

This commit is contained in:
noib3 2022-10-20 00:06:49 +02:00
parent 3d38d48c25
commit 9a7532e7a1
No known key found for this signature in database
GPG key ID: 7AF92216C504A017
3 changed files with 43 additions and 3 deletions

View file

@ -23,6 +23,7 @@ use crate::opts::*;
use crate::types::{CommandArgs, CommandInfos, KeymapInfos, Mode};
use crate::utils;
use crate::StringOrFunction;
use crate::ToApiError;
use crate::LUA_INTERNAL_CALL;
use crate::{Error, Result};
@ -368,14 +369,15 @@ impl Buffer {
/// Gets a buffer option value.
pub fn get_option<Opt>(&self, name: &str) -> Result<Opt>
where
Opt: FromObject,
Opt: TryFrom<Object>,
Opt::Error: std::error::Error + ToApiError,
{
let mut err = nvim::Error::new();
let name = nvim::String::from(name);
let obj = unsafe {
nvim_buf_get_option(self.0, name.non_owning(), &mut err)
};
choose!(err, Ok(Opt::from_object(obj)?))
choose!(err, Opt::try_from(obj).map_err(ToApiError::to_api_error))
}
/// Binding to [`nvim_buf_get_text`](https://neovim.io/doc/user/api.html#nvim_buf_get_text()).

View file

@ -1,10 +1,13 @@
use std::error::Error as StdError;
use std::fmt::Display;
use std::ptr;
use std::sync::Arc;
use thiserror::Error as ThisError;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Clone, Debug, ThisError, Eq, PartialEq)]
#[derive(Clone, Debug, ThisError)]
pub enum Error {
#[error(transparent)]
FromInt(#[from] std::num::TryFromIntError),
@ -18,6 +21,11 @@ pub enum Error {
#[error(transparent)]
ObjectConversion(#[from] nvim_types::conversion::Error),
// Using an `Arc` to be able to implement `Clone` w/o putting a `Clone`
// boundary on the type.
#[error("{0}")]
External(Arc<dyn StdError + Send + Sync>),
#[error("{0}")]
Other(String),
}
@ -27,3 +35,20 @@ impl Error {
Self::Other(msg.to_string())
}
}
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
use Error::*;
match (self, other) {
(FromInt(a), FromInt(b)) => a.eq(b),
(FromUtf8(a), FromUtf8(b)) => a.eq(b),
(Nvim(a), Nvim(b)) => a.eq(b),
(ObjectConversion(a), ObjectConversion(b)) => a.eq(b),
(Other(a), Other(b)) => a.eq(b),
(External(a), External(b)) => ptr::eq(&**a, &**b),
_ => false,
}
}
}
impl Eq for Error {}

View file

@ -1,3 +1,6 @@
use std::error::Error as StdError;
use std::sync::Arc;
use luajit_bindings::{Poppable, Pushable};
use nvim_types::{Array, Function, Object};
@ -104,3 +107,13 @@ impl<A, R> StringOrFunction<A, R> for Function<A, R> {
self.into()
}
}
pub trait ToApiError {
fn to_api_error(self) -> crate::Error;
}
impl<E: Into<Box<dyn StdError + Send + Sync>>> ToApiError for E {
fn to_api_error(self) -> crate::Error {
crate::Error::External(Arc::from(self.into()))
}
}