Use anyhow
more idiomatically (#31052)
https://github.com/zed-industries/zed/issues/30972 brought up another case where our context is not enough to track the actual source of the issue: we get a general top-level error without inner error. The reason for this was `.ok_or_else(|| anyhow!("failed to read HEAD SHA"))?; ` on the top level. The PR finally reworks the way we use anyhow to reduce such issues (or at least make it simpler to bubble them up later in a fix). On top of that, uses a few more anyhow methods for better readability. * `.ok_or_else(|| anyhow!("..."))`, `map_err` and other similar error conversion/option reporting cases are replaced with `context` and `with_context` calls * in addition to that, various `anyhow!("failed to do ...")` are stripped with `.context("Doing ...")` messages instead to remove the parasitic `failed to` text * `anyhow::ensure!` is used instead of `if ... { return Err(...); }` calls * `anyhow::bail!` is used instead of `return Err(anyhow!(...));` Release Notes: - N/A
This commit is contained in:
parent
1e51a7ac44
commit
16366cf9f2
294 changed files with 2037 additions and 2610 deletions
|
@ -1,6 +1,5 @@
|
|||
use std::{path::Path, sync::Arc, time::Duration};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use gpui::{
|
||||
Animation, AnimationExt, App, Application, Asset, AssetLogger, AssetSource, Bounds, Context,
|
||||
Hsla, ImageAssetLoader, ImageCacheError, ImgResourceLoader, LOADING_DELAY, Length, Pixels,
|
||||
|
@ -57,7 +56,7 @@ impl Asset for LoadImageWithParameters {
|
|||
timer.await;
|
||||
if parameters.fail {
|
||||
log::error!("Intentionally failed to load image");
|
||||
Err(anyhow!("Failed to load image").into())
|
||||
Err(anyhow::anyhow!("Failed to load image").into())
|
||||
} else {
|
||||
data.await
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::SharedString;
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use collections::HashMap;
|
||||
pub use no_action::{NoAction, is_no_action};
|
||||
use serde_json::json;
|
||||
|
@ -235,7 +235,7 @@ impl ActionRegistry {
|
|||
let name = self
|
||||
.names_by_type_id
|
||||
.get(type_id)
|
||||
.ok_or_else(|| anyhow!("no action type registered for {:?}", type_id))?
|
||||
.with_context(|| format!("no action type registered for {type_id:?}"))?
|
||||
.clone();
|
||||
|
||||
Ok(self.build_action(&name, None)?)
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use futures::{
|
||||
Future, FutureExt,
|
||||
|
@ -1021,9 +1021,9 @@ impl App {
|
|||
let mut window = cx
|
||||
.windows
|
||||
.get_mut(id)
|
||||
.ok_or_else(|| anyhow!("window not found"))?
|
||||
.context("window not found")?
|
||||
.take()
|
||||
.ok_or_else(|| anyhow!("window not found"))?;
|
||||
.context("window not found")?;
|
||||
|
||||
let root_view = window.root.clone().unwrap();
|
||||
|
||||
|
@ -1042,7 +1042,7 @@ impl App {
|
|||
} else {
|
||||
cx.windows
|
||||
.get_mut(id)
|
||||
.ok_or_else(|| anyhow!("window not found"))?
|
||||
.context("window not found")?
|
||||
.replace(window);
|
||||
}
|
||||
|
||||
|
@ -1119,7 +1119,7 @@ impl App {
|
|||
self.globals_by_type
|
||||
.get(&TypeId::of::<G>())
|
||||
.map(|any_state| any_state.downcast_ref::<G>().unwrap())
|
||||
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
|
||||
.with_context(|| format!("no state of type {} exists", type_name::<G>()))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
@ -1138,7 +1138,7 @@ impl App {
|
|||
self.globals_by_type
|
||||
.get_mut(&global_type)
|
||||
.and_then(|any_state| any_state.downcast_mut::<G>())
|
||||
.ok_or_else(|| anyhow!("no state of type {} exists", type_name::<G>()))
|
||||
.with_context(|| format!("no state of type {} exists", type_name::<G>()))
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
@ -1201,7 +1201,7 @@ impl App {
|
|||
GlobalLease::new(
|
||||
self.globals_by_type
|
||||
.remove(&TypeId::of::<G>())
|
||||
.ok_or_else(|| anyhow!("no global registered of type {}", type_name::<G>()))
|
||||
.with_context(|| format!("no global registered of type {}", type_name::<G>()))
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
|
@ -1765,7 +1765,7 @@ impl AppContext for App {
|
|||
let window = self
|
||||
.windows
|
||||
.get(window.id)
|
||||
.ok_or_else(|| anyhow!("window not found"))?
|
||||
.context("window not found")?
|
||||
.as_ref()
|
||||
.expect("attempted to read a window that is already on the stack");
|
||||
|
||||
|
@ -1915,9 +1915,12 @@ impl HttpClient for NullHttpClient {
|
|||
_req: http_client::Request<http_client::AsyncBody>,
|
||||
) -> futures::future::BoxFuture<
|
||||
'static,
|
||||
Result<http_client::Response<http_client::AsyncBody>, anyhow::Error>,
|
||||
anyhow::Result<http_client::Response<http_client::AsyncBody>>,
|
||||
> {
|
||||
async move { Err(anyhow!("No HttpClient available")) }.boxed()
|
||||
async move {
|
||||
anyhow::bail!("No HttpClient available");
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn proxy(&self) -> Option<&Url> {
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
Entity, EventEmitter, Focusable, ForegroundExecutor, Global, PromptLevel, Render, Reservation,
|
||||
Result, Subscription, Task, VisualContext, Window, WindowHandle,
|
||||
};
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use anyhow::Context as _;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use futures::channel::oneshot;
|
||||
use std::{future::Future, rc::Weak};
|
||||
|
@ -27,19 +27,13 @@ impl AppContext for AsyncApp {
|
|||
&mut self,
|
||||
build_entity: impl FnOnce(&mut Context<T>) -> T,
|
||||
) -> Self::Result<Entity<T>> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.new(build_entity))
|
||||
}
|
||||
|
||||
fn reserve_entity<T: 'static>(&mut self) -> Result<Reservation<T>> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.reserve_entity())
|
||||
}
|
||||
|
@ -49,10 +43,7 @@ impl AppContext for AsyncApp {
|
|||
reservation: Reservation<T>,
|
||||
build_entity: impl FnOnce(&mut Context<T>) -> T,
|
||||
) -> Result<Entity<T>> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.insert_entity(reservation, build_entity))
|
||||
}
|
||||
|
@ -62,10 +53,7 @@ impl AppContext for AsyncApp {
|
|||
handle: &Entity<T>,
|
||||
update: impl FnOnce(&mut T, &mut Context<T>) -> R,
|
||||
) -> Self::Result<R> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.update_entity(handle, update))
|
||||
}
|
||||
|
@ -125,10 +113,7 @@ impl AppContext for AsyncApp {
|
|||
impl AsyncApp {
|
||||
/// Schedules all windows in the application to be redrawn.
|
||||
pub fn refresh(&self) -> Result<()> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut lock = app.borrow_mut();
|
||||
lock.refresh_windows();
|
||||
Ok(())
|
||||
|
@ -146,10 +131,7 @@ impl AsyncApp {
|
|||
|
||||
/// Invoke the given function in the context of the app, then flush any effects produced during its invocation.
|
||||
pub fn update<R>(&self, f: impl FnOnce(&mut App) -> R) -> Result<R> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut lock = app.borrow_mut();
|
||||
Ok(lock.update(f))
|
||||
}
|
||||
|
@ -165,10 +147,7 @@ impl AsyncApp {
|
|||
T: 'static + EventEmitter<Event>,
|
||||
Event: 'static,
|
||||
{
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut lock = app.borrow_mut();
|
||||
let subscription = lock.subscribe(entity, on_event);
|
||||
Ok(subscription)
|
||||
|
@ -183,10 +162,7 @@ impl AsyncApp {
|
|||
where
|
||||
V: 'static + Render,
|
||||
{
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut lock = app.borrow_mut();
|
||||
lock.open_window(options, build_root_view)
|
||||
}
|
||||
|
@ -206,10 +182,7 @@ impl AsyncApp {
|
|||
/// Determine whether global state of the specified type has been assigned.
|
||||
/// Returns an error if the `App` has been dropped.
|
||||
pub fn has_global<G: Global>(&self) -> Result<bool> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let app = app.borrow_mut();
|
||||
Ok(app.has_global::<G>())
|
||||
}
|
||||
|
@ -219,10 +192,7 @@ impl AsyncApp {
|
|||
/// Panics if no global state of the specified type has been assigned.
|
||||
/// Returns an error if the `App` has been dropped.
|
||||
pub fn read_global<G: Global, R>(&self, read: impl FnOnce(&G, &App) -> R) -> Result<R> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let app = app.borrow_mut();
|
||||
Ok(read(app.global(), &app))
|
||||
}
|
||||
|
@ -245,10 +215,7 @@ impl AsyncApp {
|
|||
&self,
|
||||
update: impl FnOnce(&mut G, &mut App) -> R,
|
||||
) -> Result<R> {
|
||||
let app = self
|
||||
.app
|
||||
.upgrade()
|
||||
.ok_or_else(|| anyhow!("app was released"))?;
|
||||
let app = self.app.upgrade().context("app was released")?;
|
||||
let mut app = app.borrow_mut();
|
||||
Ok(app.update(|cx| cx.update_global(update)))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{App, AppContext, VisualContext, Window, seal::Sealed};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use collections::FxHashSet;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
|
||||
|
@ -692,7 +692,7 @@ impl<T: 'static> WeakEntity<T> {
|
|||
{
|
||||
crate::Flatten::flatten(
|
||||
self.upgrade()
|
||||
.ok_or_else(|| anyhow!("entity released"))
|
||||
.context("entity released")
|
||||
.map(|this| cx.update_entity(&this, update)),
|
||||
)
|
||||
}
|
||||
|
@ -710,7 +710,7 @@ impl<T: 'static> WeakEntity<T> {
|
|||
Result<C::Result<R>>: crate::Flatten<R>,
|
||||
{
|
||||
let window = cx.window_handle();
|
||||
let this = self.upgrade().ok_or_else(|| anyhow!("entity released"))?;
|
||||
let this = self.upgrade().context("entity released")?;
|
||||
|
||||
crate::Flatten::flatten(window.update(cx, |_, window, cx| {
|
||||
this.update(cx, |entity, cx| update(entity, window, cx))
|
||||
|
@ -727,7 +727,7 @@ impl<T: 'static> WeakEntity<T> {
|
|||
{
|
||||
crate::Flatten::flatten(
|
||||
self.upgrade()
|
||||
.ok_or_else(|| anyhow!("entity release"))
|
||||
.context("entity released")
|
||||
.map(|this| cx.read_entity(&this, read)),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::{Context, bail};
|
||||
use anyhow::{Context as _, bail};
|
||||
use serde::de::{self, Deserialize, Deserializer, Visitor};
|
||||
use std::{
|
||||
fmt::{self, Display, Formatter},
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
SMOOTH_SVG_SCALE_FACTOR, SharedString, SharedUri, StyleRefinement, Styled, SvgSize, Task,
|
||||
Window, px, swap_rgba_pa_to_bgra,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
|
||||
use futures::{AsyncReadExt, Future};
|
||||
use image::{
|
||||
|
@ -595,7 +595,7 @@ impl Asset for ImageAssetLoader {
|
|||
let mut response = client
|
||||
.get(uri.as_ref(), ().into(), true)
|
||||
.await
|
||||
.map_err(|e| anyhow!(e))?;
|
||||
.with_context(|| format!("loading image asset from {uri:?}"))?;
|
||||
let mut body = Vec::new();
|
||||
response.body_mut().read_to_end(&mut body).await?;
|
||||
if !response.status().is_success() {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
Pixels, Point, SharedString, Size, TextOverflow, TextRun, TextStyle, TooltipId, WhiteSpace,
|
||||
Window, WrappedLine, WrappedLineLayout, register_tooltip_mouse_handlers, set_tooltip_on_window,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use anyhow::Context as _;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
cell::{Cell, RefCell},
|
||||
|
@ -401,7 +401,7 @@ impl TextLayout {
|
|||
let mut element_state = self.0.borrow_mut();
|
||||
let element_state = element_state
|
||||
.as_mut()
|
||||
.ok_or_else(|| anyhow!("measurement has not been performed on {}", text))
|
||||
.with_context(|| format!("measurement has not been performed on {text}"))
|
||||
.unwrap();
|
||||
element_state.bounds = Some(bounds);
|
||||
}
|
||||
|
@ -410,11 +410,11 @@ impl TextLayout {
|
|||
let element_state = self.0.borrow();
|
||||
let element_state = element_state
|
||||
.as_ref()
|
||||
.ok_or_else(|| anyhow!("measurement has not been performed on {}", text))
|
||||
.with_context(|| format!("measurement has not been performed on {text}"))
|
||||
.unwrap();
|
||||
let bounds = element_state
|
||||
.bounds
|
||||
.ok_or_else(|| anyhow!("prepaint has not been performed on {:?}", text))
|
||||
.with_context(|| format!("prepaint has not been performed on {text}"))
|
||||
.unwrap();
|
||||
|
||||
let line_height = element_state.line_height;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::SharedString;
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use std::fmt;
|
||||
|
||||
/// A datastructure for resolving whether an action should be dispatched
|
||||
|
@ -243,7 +243,7 @@ impl KeyBindingContextPredicate {
|
|||
let source = skip_whitespace(source);
|
||||
let (predicate, rest) = Self::parse_expr(source, 0)?;
|
||||
if let Some(next) = rest.chars().next() {
|
||||
Err(anyhow!("unexpected character '{next:?}'"))
|
||||
anyhow::bail!("unexpected character '{next:?}'");
|
||||
} else {
|
||||
Ok(predicate)
|
||||
}
|
||||
|
@ -329,20 +329,14 @@ impl KeyBindingContextPredicate {
|
|||
}
|
||||
|
||||
fn parse_primary(mut source: &str) -> anyhow::Result<(Self, &str)> {
|
||||
let next = source
|
||||
.chars()
|
||||
.next()
|
||||
.ok_or_else(|| anyhow!("unexpected end"))?;
|
||||
let next = source.chars().next().context("unexpected end")?;
|
||||
match next {
|
||||
'(' => {
|
||||
source = skip_whitespace(&source[1..]);
|
||||
let (predicate, rest) = Self::parse_expr(source, 0)?;
|
||||
if let Some(stripped) = rest.strip_prefix(')') {
|
||||
source = skip_whitespace(stripped);
|
||||
Ok((predicate, source))
|
||||
} else {
|
||||
Err(anyhow!("expected a ')'"))
|
||||
}
|
||||
let stripped = rest.strip_prefix(')').context("expected a ')'")?;
|
||||
source = skip_whitespace(stripped);
|
||||
Ok((predicate, source))
|
||||
}
|
||||
'!' => {
|
||||
let source = skip_whitespace(&source[1..]);
|
||||
|
@ -368,7 +362,7 @@ impl KeyBindingContextPredicate {
|
|||
source,
|
||||
))
|
||||
}
|
||||
_ => Err(anyhow!("unexpected character '{next:?}'")),
|
||||
_ => anyhow::bail!("unexpected character '{next:?}'"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,7 +382,7 @@ impl KeyBindingContextPredicate {
|
|||
if let (Self::Identifier(left), Self::Identifier(right)) = (self, other) {
|
||||
Ok(Self::Equal(left, right))
|
||||
} else {
|
||||
Err(anyhow!("operands of == must be identifiers"))
|
||||
anyhow::bail!("operands of == must be identifiers");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -396,7 +390,7 @@ impl KeyBindingContextPredicate {
|
|||
if let (Self::Identifier(left), Self::Identifier(right)) = (self, other) {
|
||||
Ok(Self::NotEqual(left, right))
|
||||
} else {
|
||||
Err(anyhow!("operands of != must be identifiers"))
|
||||
anyhow::bail!("operands of != must be identifiers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ impl BladeContext {
|
|||
..Default::default()
|
||||
})
|
||||
}
|
||||
.map_err(|e| anyhow::anyhow!("{:?}", e))?,
|
||||
.map_err(|e| anyhow::anyhow!("{e:?}"))?,
|
||||
);
|
||||
Ok(Self { gpu })
|
||||
}
|
||||
|
@ -49,8 +49,7 @@ fn parse_pci_id(id: &str) -> anyhow::Result<u32> {
|
|||
"Expected a 4 digit PCI ID in hexadecimal format"
|
||||
);
|
||||
|
||||
return u32::from_str_radix(id, 16)
|
||||
.map_err(|_| anyhow::anyhow!("Failed to parse PCI ID as hex"));
|
||||
return u32::from_str_radix(id, 16).context("parsing PCI ID as hex");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -95,9 +95,7 @@ impl LinuxClient for HeadlessClient {
|
|||
_handle: AnyWindowHandle,
|
||||
_params: WindowParams,
|
||||
) -> anyhow::Result<Box<dyn PlatformWindow>> {
|
||||
Err(anyhow::anyhow!(
|
||||
"neither DISPLAY nor WAYLAND_DISPLAY is set. You can run in headless mode"
|
||||
))
|
||||
anyhow::bail!("neither DISPLAY nor WAYLAND_DISPLAY is set. You can run in headless mode");
|
||||
}
|
||||
|
||||
fn compositor_name(&self) -> &'static str {
|
||||
|
|
|
@ -490,7 +490,7 @@ impl<P: LinuxClient + 'static> Platform for P {
|
|||
let attributes = item.attributes().await?;
|
||||
let username = attributes
|
||||
.get("username")
|
||||
.ok_or_else(|| anyhow!("Cannot find username in stored credentials"))?;
|
||||
.context("Cannot find username in stored credentials")?;
|
||||
let secret = item.secret().await?;
|
||||
|
||||
// we lose the zeroizing capabilities at this boundary,
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::{
|
|||
GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, RenderGlyphParams, SUBPIXEL_VARIANTS,
|
||||
ShapedGlyph, ShapedRun, SharedString, Size, point, size,
|
||||
};
|
||||
use anyhow::{Context as _, Ok, Result, anyhow};
|
||||
use anyhow::{Context as _, Ok, Result};
|
||||
use collections::HashMap;
|
||||
use cosmic_text::{
|
||||
Attrs, AttrsList, CacheKey, Family, Font as CosmicTextFont, FontFeatures as CosmicFontFeatures,
|
||||
|
@ -232,7 +232,7 @@ impl CosmicTextSystemState {
|
|||
let font = self
|
||||
.font_system
|
||||
.get_font(font_id)
|
||||
.ok_or_else(|| anyhow!("Could not load font"))?;
|
||||
.context("Could not load font")?;
|
||||
|
||||
// HACK: To let the storybook run and render Windows caption icons. We should actually do better font fallback.
|
||||
let allowed_bad_font_names = [
|
||||
|
@ -309,7 +309,7 @@ impl CosmicTextSystemState {
|
|||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||
if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
|
||||
Err(anyhow!("glyph bounds are empty"))
|
||||
anyhow::bail!("glyph bounds are empty");
|
||||
} else {
|
||||
let bitmap_size = glyph_bounds.size;
|
||||
let font = &self.loaded_fonts[params.font_id.0].font;
|
||||
|
@ -469,7 +469,7 @@ impl TryFrom<&FontFeatures> for CosmicFontFeatures {
|
|||
.0
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.map_err(|_| anyhow!("Incorrect feature flag format"))?;
|
||||
.context("Incorrect feature flag format")?;
|
||||
|
||||
let tag = cosmic_text::FeatureTag::new(&name_bytes);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::{
|
|||
hash::{Hash, Hasher},
|
||||
};
|
||||
|
||||
use anyhow::Context as _;
|
||||
use uuid::Uuid;
|
||||
use wayland_backend::client::ObjectId;
|
||||
|
||||
|
@ -28,11 +29,11 @@ impl PlatformDisplay for WaylandDisplay {
|
|||
}
|
||||
|
||||
fn uuid(&self) -> anyhow::Result<Uuid> {
|
||||
if let Some(name) = &self.name {
|
||||
Ok(Uuid::new_v5(&Uuid::NAMESPACE_DNS, name.as_bytes()))
|
||||
} else {
|
||||
Err(anyhow::anyhow!("Wayland display does not have a name"))
|
||||
}
|
||||
let name = self
|
||||
.name
|
||||
.as_ref()
|
||||
.context("Wayland display does not have a name")?;
|
||||
Ok(Uuid::new_v5(&Uuid::NAMESPACE_DNS, name.as_bytes()))
|
||||
}
|
||||
|
||||
fn bounds(&self) -> Bounds<Pixels> {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use anyhow::Result;
|
||||
use anyhow::Context as _;
|
||||
use uuid::Uuid;
|
||||
use x11rb::{connection::Connection as _, xcb_ffi::XCBConnection};
|
||||
|
||||
|
@ -17,12 +17,11 @@ impl X11Display {
|
|||
scale_factor: f32,
|
||||
x_screen_index: usize,
|
||||
) -> anyhow::Result<Self> {
|
||||
let Some(screen) = xcb.setup().roots.get(x_screen_index) else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No screen found with index {}",
|
||||
x_screen_index
|
||||
));
|
||||
};
|
||||
let screen = xcb
|
||||
.setup()
|
||||
.roots
|
||||
.get(x_screen_index)
|
||||
.with_context(|| format!("No screen found with index {x_screen_index}"))?;
|
||||
Ok(Self {
|
||||
x_screen_index,
|
||||
bounds: Bounds {
|
||||
|
@ -42,7 +41,7 @@ impl PlatformDisplay for X11Display {
|
|||
DisplayId(self.x_screen_index as u32)
|
||||
}
|
||||
|
||||
fn uuid(&self) -> Result<Uuid> {
|
||||
fn uuid(&self) -> anyhow::Result<Uuid> {
|
||||
Ok(self.uuid)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
AtlasKey, AtlasTextureId, AtlasTextureKind, AtlasTile, Bounds, DevicePixels, PlatformAtlas,
|
||||
Point, Size, platform::AtlasTextureList,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use collections::FxHashMap;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use etagere::BucketedAtlasAllocator;
|
||||
|
@ -77,7 +77,7 @@ impl PlatformAtlas for MetalAtlas {
|
|||
};
|
||||
let tile = lock
|
||||
.allocate(size, key.texture_kind())
|
||||
.ok_or_else(|| anyhow!("failed to allocate"))?;
|
||||
.context("failed to allocate")?;
|
||||
let texture = lock.texture(tile.texture_id);
|
||||
texture.upload(tile.bounds, &bytes);
|
||||
lock.tiles_by_key.insert(key.clone(), tile.clone());
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
MonochromeSprite, PaintSurface, Path, PathId, PathVertex, PolychromeSprite, PrimitiveBatch,
|
||||
Quad, ScaledPixels, Scene, Shadow, Size, Surface, Underline, point, size,
|
||||
};
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Context as _, Result};
|
||||
use block::ConcreteBlock;
|
||||
use cocoa::{
|
||||
base::{NO, YES},
|
||||
|
@ -376,14 +376,14 @@ impl MetalRenderer {
|
|||
let command_buffer = command_queue.new_command_buffer();
|
||||
let mut instance_offset = 0;
|
||||
|
||||
let Some(path_tiles) = self.rasterize_paths(
|
||||
scene.paths(),
|
||||
instance_buffer,
|
||||
&mut instance_offset,
|
||||
command_buffer,
|
||||
) else {
|
||||
return Err(anyhow!("failed to rasterize {} paths", scene.paths().len()));
|
||||
};
|
||||
let path_tiles = self
|
||||
.rasterize_paths(
|
||||
scene.paths(),
|
||||
instance_buffer,
|
||||
&mut instance_offset,
|
||||
command_buffer,
|
||||
)
|
||||
.with_context(|| format!("rasterizing {} paths", scene.paths().len()))?;
|
||||
|
||||
let render_pass_descriptor = metal::RenderPassDescriptor::new();
|
||||
let color_attachment = render_pass_descriptor
|
||||
|
@ -471,7 +471,7 @@ impl MetalRenderer {
|
|||
|
||||
if !ok {
|
||||
command_encoder.end_encoding();
|
||||
return Err(anyhow!(
|
||||
anyhow::bail!(
|
||||
"scene too large: {} paths, {} shadows, {} quads, {} underlines, {} mono, {} poly, {} surfaces",
|
||||
scene.paths.len(),
|
||||
scene.shadows.len(),
|
||||
|
@ -480,7 +480,7 @@ impl MetalRenderer {
|
|||
scene.monochrome_sprites.len(),
|
||||
scene.polychrome_sprites.len(),
|
||||
scene.surfaces.len(),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -638,7 +638,7 @@ impl Platform for MacPlatform {
|
|||
Ok(())
|
||||
} else {
|
||||
let msg: id = msg_send![error, localizedDescription];
|
||||
Err(anyhow!("Failed to register: {:?}", msg))
|
||||
Err(anyhow!("Failed to register: {msg:?}"))
|
||||
};
|
||||
|
||||
if let Some(done_tx) = done_tx.take() {
|
||||
|
@ -832,11 +832,8 @@ impl Platform for MacPlatform {
|
|||
fn app_path(&self) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
Ok(path_from_objc(msg_send![bundle, bundlePath]))
|
||||
}
|
||||
anyhow::ensure!(!bundle.is_null(), "app is not running inside a bundle");
|
||||
Ok(path_from_objc(msg_send![bundle, bundlePath]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -877,17 +874,11 @@ impl Platform for MacPlatform {
|
|||
fn path_for_auxiliary_executable(&self, name: &str) -> Result<PathBuf> {
|
||||
unsafe {
|
||||
let bundle: id = NSBundle::mainBundle();
|
||||
if bundle.is_null() {
|
||||
Err(anyhow!("app is not running inside a bundle"))
|
||||
} else {
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
if url.is_null() {
|
||||
Err(anyhow!("resource not found"))
|
||||
} else {
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
anyhow::ensure!(!bundle.is_null(), "app is not running inside a bundle");
|
||||
let name = ns_string(name);
|
||||
let url: id = msg_send![bundle, URLForAuxiliaryExecutable: name];
|
||||
anyhow::ensure!(!url.is_null(), "resource not found");
|
||||
ns_url_to_path(url)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1101,10 +1092,7 @@ impl Platform for MacPlatform {
|
|||
verb = "creating";
|
||||
status = SecItemAdd(attrs.as_concrete_TypeRef(), ptr::null_mut());
|
||||
}
|
||||
|
||||
if status != errSecSuccess {
|
||||
return Err(anyhow!("{} password failed: {}", verb, status));
|
||||
}
|
||||
anyhow::ensure!(status == errSecSuccess, "{verb} password failed: {status}");
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -1131,24 +1119,24 @@ impl Platform for MacPlatform {
|
|||
match status {
|
||||
security::errSecSuccess => {}
|
||||
security::errSecItemNotFound | security::errSecUserCanceled => return Ok(None),
|
||||
_ => return Err(anyhow!("reading password failed: {}", status)),
|
||||
_ => anyhow::bail!("reading password failed: {status}"),
|
||||
}
|
||||
|
||||
let result = CFType::wrap_under_create_rule(result)
|
||||
.downcast::<CFDictionary>()
|
||||
.ok_or_else(|| anyhow!("keychain item was not a dictionary"))?;
|
||||
.context("keychain item was not a dictionary")?;
|
||||
let username = result
|
||||
.find(kSecAttrAccount as *const _)
|
||||
.ok_or_else(|| anyhow!("account was missing from keychain item"))?;
|
||||
.context("account was missing from keychain item")?;
|
||||
let username = CFType::wrap_under_get_rule(*username)
|
||||
.downcast::<CFString>()
|
||||
.ok_or_else(|| anyhow!("account was not a string"))?;
|
||||
.context("account was not a string")?;
|
||||
let password = result
|
||||
.find(kSecValueData as *const _)
|
||||
.ok_or_else(|| anyhow!("password was missing from keychain item"))?;
|
||||
.context("password was missing from keychain item")?;
|
||||
let password = CFType::wrap_under_get_rule(*password)
|
||||
.downcast::<CFData>()
|
||||
.ok_or_else(|| anyhow!("password was not a string"))?;
|
||||
.context("password was not a string")?;
|
||||
|
||||
Ok(Some((username.to_string(), password.bytes().to_vec())))
|
||||
}
|
||||
|
@ -1168,10 +1156,7 @@ impl Platform for MacPlatform {
|
|||
query_attrs.set(kSecAttrServer as *const _, url.as_CFTypeRef());
|
||||
|
||||
let status = SecItemDelete(query_attrs.as_concrete_TypeRef());
|
||||
|
||||
if status != errSecSuccess {
|
||||
return Err(anyhow!("delete password failed: {}", status));
|
||||
}
|
||||
anyhow::ensure!(status == errSecSuccess, "delete password failed: {status}");
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
|
@ -1455,15 +1440,12 @@ unsafe fn ns_string(string: &str) -> id {
|
|||
|
||||
unsafe fn ns_url_to_path(url: id) -> Result<PathBuf> {
|
||||
let path: *mut c_char = msg_send![url, fileSystemRepresentation];
|
||||
if path.is_null() {
|
||||
Err(anyhow!("url is not a file path: {}", unsafe {
|
||||
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
|
||||
}))
|
||||
} else {
|
||||
Ok(PathBuf::from(OsStr::from_bytes(unsafe {
|
||||
CStr::from_ptr(path).to_bytes()
|
||||
})))
|
||||
}
|
||||
anyhow::ensure!(!path.is_null(), "url is not a file path: {}", unsafe {
|
||||
CStr::from_ptr(url.absoluteString().UTF8String()).to_string_lossy()
|
||||
});
|
||||
Ok(PathBuf::from(OsStr::from_bytes(unsafe {
|
||||
CStr::from_ptr(path).to_bytes()
|
||||
})))
|
||||
}
|
||||
|
||||
#[link(name = "Carbon", kind = "framework")]
|
||||
|
|
|
@ -194,7 +194,7 @@ impl MacTextSystemState {
|
|||
core_graphics::data_provider::CGDataProvider::from_slice(embedded_font)
|
||||
};
|
||||
let font = core_graphics::font::CGFont::from_data_provider(data_provider)
|
||||
.map_err(|_| anyhow!("Could not load an embedded font."))?;
|
||||
.map_err(|()| anyhow!("Could not load an embedded font."))?;
|
||||
let font = font_kit::loaders::core_text::Font::from_core_graphics_font(font);
|
||||
Ok(Handle::from_native(&font))
|
||||
}
|
||||
|
@ -348,7 +348,7 @@ impl MacTextSystemState {
|
|||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||
if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
|
||||
Err(anyhow!("glyph bounds are empty"))
|
||||
anyhow::bail!("glyph bounds are empty");
|
||||
} else {
|
||||
// Add an extra pixel when the subpixel variant isn't zero to make room for anti-aliasing.
|
||||
let mut bitmap_size = glyph_bounds.size;
|
||||
|
|
|
@ -54,9 +54,7 @@ impl DockMenuItem {
|
|||
},
|
||||
action,
|
||||
}),
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"Only `MenuItem::Action` is supported for dock menu on Windows."
|
||||
)),
|
||||
_ => anyhow::bail!("Only `MenuItem::Action` is supported for dock menu on Windows."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::Result;
|
||||
use collections::HashMap;
|
||||
use itertools::Itertools;
|
||||
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
|
||||
|
@ -729,7 +729,7 @@ impl DirectWriteState {
|
|||
glyph_bounds: Bounds<DevicePixels>,
|
||||
) -> Result<(Size<DevicePixels>, Vec<u8>)> {
|
||||
if glyph_bounds.size.width.0 == 0 || glyph_bounds.size.height.0 == 0 {
|
||||
return Err(anyhow!("glyph bounds are empty"));
|
||||
anyhow::bail!("glyph bounds are empty");
|
||||
}
|
||||
|
||||
let font_info = &self.fonts[params.font_id.0];
|
||||
|
@ -1301,7 +1301,7 @@ fn get_postscript_name(font_face: &IDWriteFontFace3, locale: &str) -> Result<Str
|
|||
)?
|
||||
};
|
||||
if !exists.as_bool() || info.is_none() {
|
||||
return Err(anyhow!("No postscript name found for font face"));
|
||||
anyhow::bail!("No postscript name found for font face");
|
||||
}
|
||||
|
||||
get_name(info.unwrap(), locale)
|
||||
|
@ -1393,9 +1393,7 @@ fn get_name(string: IDWriteLocalizedStrings, locale: &str) -> Result<String> {
|
|||
&mut exists as _,
|
||||
)?
|
||||
};
|
||||
if !exists.as_bool() {
|
||||
return Err(anyhow!("No localised string for {}", locale));
|
||||
}
|
||||
anyhow::ensure!(exists.as_bool(), "No localised string for {locale}");
|
||||
}
|
||||
|
||||
let name_length = unsafe { string.GetStringLength(locale_name_index) }? as usize;
|
||||
|
|
|
@ -576,7 +576,7 @@ impl Platform for WindowsPlatform {
|
|||
|
||||
// todo(windows)
|
||||
fn path_for_auxiliary_executable(&self, _name: &str) -> Result<PathBuf> {
|
||||
Err(anyhow!("not yet implemented"))
|
||||
anyhow::bail!("not yet implemented");
|
||||
}
|
||||
|
||||
fn set_cursor_style(&self, style: CursorStyle) {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use crate::{AssetSource, DevicePixels, IsZero, Result, SharedString, Size};
|
||||
use anyhow::anyhow;
|
||||
use resvg::tiny_skia::Pixmap;
|
||||
use std::{
|
||||
hash::Hash,
|
||||
|
@ -56,9 +55,7 @@ impl SvgRenderer {
|
|||
}
|
||||
|
||||
pub(crate) fn render(&self, params: &RenderSvgParams) -> Result<Option<Vec<u8>>> {
|
||||
if params.size.is_zero() {
|
||||
return Err(anyhow!("can't render at a zero size"));
|
||||
}
|
||||
anyhow::ensure!(!params.size.is_zero(), "can't render at a zero size");
|
||||
|
||||
// Load the tree.
|
||||
let Some(bytes) = self.asset_source.load(¶ms.path)? else {
|
||||
|
|
|
@ -16,7 +16,7 @@ use crate::{
|
|||
Bounds, DevicePixels, Hsla, Pixels, PlatformTextSystem, Point, Result, SharedString, Size,
|
||||
StrikethroughStyle, UnderlineStyle, px,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use collections::FxHashMap;
|
||||
use core::fmt;
|
||||
use derive_more::Deref;
|
||||
|
@ -100,7 +100,7 @@ impl TextSystem {
|
|||
fn clone_font_id_result(font_id: &Result<FontId>) -> Result<FontId> {
|
||||
match font_id {
|
||||
Ok(font_id) => Ok(*font_id),
|
||||
Err(err) => Err(anyhow!("{}", err)),
|
||||
Err(err) => Err(anyhow!("{err}")),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ impl TextSystem {
|
|||
let glyph_id = self
|
||||
.platform_text_system
|
||||
.glyph_for_char(font_id, character)
|
||||
.ok_or_else(|| anyhow!("glyph not found for character '{}'", character))?;
|
||||
.with_context(|| format!("glyph not found for character '{character}'"))?;
|
||||
let bounds = self
|
||||
.platform_text_system
|
||||
.typographic_bounds(font_id, glyph_id)?;
|
||||
|
@ -188,7 +188,7 @@ impl TextSystem {
|
|||
let glyph_id = self
|
||||
.platform_text_system
|
||||
.glyph_for_char(font_id, ch)
|
||||
.ok_or_else(|| anyhow!("glyph not found for character '{}'", ch))?;
|
||||
.with_context(|| format!("glyph not found for character '{ch}'"))?;
|
||||
let result = self.platform_text_system.advance(font_id, glyph_id)?
|
||||
/ self.units_per_em(font_id) as f32;
|
||||
|
||||
|
|
|
@ -3922,7 +3922,7 @@ impl<V: 'static + Render> WindowHandle<V> {
|
|||
.and_then(|window| window.root.clone())
|
||||
.map(|root_view| root_view.downcast::<V>())
|
||||
})
|
||||
.ok_or_else(|| anyhow!("window not found"))?
|
||||
.context("window not found")?
|
||||
.map_err(|_| anyhow!("the type of the window's root view has changed"))?;
|
||||
|
||||
Ok(x.read(cx))
|
||||
|
@ -4103,7 +4103,7 @@ impl TryInto<SharedString> for ElementId {
|
|||
if let ElementId::Name(name) = self {
|
||||
Ok(name)
|
||||
} else {
|
||||
Err(anyhow!("element id is not string"))
|
||||
anyhow::bail!("element id is not string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue