Yeet try_blocks 😢

This commit is contained in:
elkowar 2024-02-17 12:59:41 +01:00 committed by ElKowar
parent 0eed19332b
commit 60ab81ac13
14 changed files with 211 additions and 205 deletions

View file

@ -146,10 +146,16 @@ impl<B> std::fmt::Debug for App<B> {
}
impl<B: DisplayBackend> App<B> {
/// Handle a [`DaemonCommand`] event.
/// Handle a [`DaemonCommand`] event, logging any errors that occur.
pub fn handle_command(&mut self, event: DaemonCommand) {
if let Err(err) = self.try_handle_command(event) {
error_handling_ctx::print_error(err);
}
}
/// Try to handle a [`DaemonCommand`] event.
fn try_handle_command(&mut self, event: DaemonCommand) -> Result<()> {
log::debug!("Handling event: {:?}", &event);
let result: Result<_> = try {
match event {
DaemonCommand::NoOp => {}
DaemonCommand::OpenInspector => {
@ -204,11 +210,7 @@ impl<B: DisplayBackend> App<B> {
.filter(|(win_id, ..)| win_id.is_empty() || win_id == id)
.map(|(_, n, v)| (n.clone(), v.clone()))
.collect();
self.open_window(&WindowArguments::new_from_args(
id.to_string(),
config_name.clone(),
window_args,
)?)
self.open_window(&WindowArguments::new_from_args(id.to_string(), config_name.clone(), window_args)?)
}
})
.filter_map(Result::err);
@ -285,11 +287,7 @@ impl<B: DisplayBackend> App<B> {
}
DaemonCommand::PrintGraph(sender) => sender.send_success(self.scope_graph.borrow().visualize())?,
}
};
if let Err(err) = result {
error_handling_ctx::print_error(err);
}
Ok(())
}
/// Fully stop eww:
@ -375,7 +373,7 @@ impl<B: DisplayBackend> App<B> {
self.instance_id_to_args.insert(instance_id.to_string(), window_args.clone());
let open_result: Result<_> = try {
let open_result: Result<_> = (|| {
let window_name: &str = &window_args.window_name;
let window_def = self.eww_config.get_window(window_name)?.clone();
@ -461,7 +459,8 @@ impl<B: DisplayBackend> App<B> {
}
self.open_windows.insert(instance_id.to_string(), eww_window);
};
Ok(())
})();
if let Err(err) = open_result {
self.failed_windows.insert(instance_id.to_string());
@ -499,15 +498,15 @@ impl<B: DisplayBackend> App<B> {
pub fn load_css(&mut self, file_id: usize, css: &str) -> Result<()> {
if let Err(err) = self.css_provider.load_from_data(css.as_bytes()) {
static PATTERN: Lazy<regex::Regex> = Lazy::new(|| regex::Regex::new(r"[^:]*:(\d+):(\d+)(.*)$").unwrap());
let nice_error_option: Option<_> = try {
let nice_error_option: Option<_> = (|| {
let captures = PATTERN.captures(err.message())?;
let line = captures.get(1).unwrap().as_str().parse::<usize>().ok()?;
let msg = captures.get(3).unwrap().as_str();
let db = error_handling_ctx::FILE_DATABASE.read().ok()?;
let line_range = db.line_range(file_id, line - 1).ok()?;
let span = Span(line_range.start, line_range.end - 1, file_id);
DiagError(gen_diagnostic!(msg, span))
};
Some(DiagError(gen_diagnostic!(msg, span)))
})();
match nice_error_option {
Some(error) => Err(anyhow!(error)),
None => Err(anyhow!("CSS error: {}", err.message())),

View file

@ -1,4 +1,3 @@
#![feature(try_blocks)]
#![allow(rustdoc::private_intra_doc_links)]
extern crate gtk;

View file

@ -33,7 +33,7 @@ pub fn init(evt_send: UnboundedSender<DaemonCommand>) -> ScriptVarHandlerHandle
.build()
.expect("Failed to initialize tokio runtime for script var handlers");
rt.block_on(async {
let _: Result<_> = try {
let _: Result<_> = async {
let mut handler = ScriptVarHandler {
listen_handler: ListenVarHandler::new(evt_send.clone())?,
poll_handler: PollVarHandler::new(evt_send)?,
@ -53,7 +53,9 @@ pub fn init(evt_send: UnboundedSender<DaemonCommand>) -> ScriptVarHandlerHandle
},
else => break,
};
};
Ok(())
}
.await;
})
})
.expect("Failed to start script-var-handler thread");
@ -158,9 +160,10 @@ impl PollVarHandler {
self.poll_handles.insert(var.name.clone(), cancellation_token.clone());
let evt_send = self.evt_send.clone();
tokio::spawn(async move {
let result: Result<_> = try {
let result: Result<_> = (|| {
evt_send.send(app::DaemonCommand::UpdateVars(vec![(var.name.clone(), run_poll_once(&var)?)]))?;
};
Ok(())
})();
if let Err(err) = result {
crate::error_handling_ctx::print_error(err);
}
@ -168,9 +171,10 @@ impl PollVarHandler {
crate::loop_select_exiting! {
_ = cancellation_token.cancelled() => break,
_ = tokio::time::sleep(var.interval) => {
let result: Result<_> = try {
let result: Result<_> = (|| {
evt_send.send(app::DaemonCommand::UpdateVars(vec![(var.name.clone(), run_poll_once(&var)?)]))?;
};
Ok(())
})();
if let Err(err) = result {
crate::error_handling_ctx::print_error(err);
@ -233,7 +237,7 @@ impl ListenVarHandler {
let evt_send = self.evt_send.clone();
tokio::spawn(async move {
crate::try_logging_errors!(format!("Executing listen var-command {}", &var.command) => {
let result: Result<_> = async {
let mut handle = unsafe {
tokio::process::Command::new("sh")
.args(["-c", &var.command])
@ -243,7 +247,8 @@ impl ListenVarHandler {
.pre_exec(|| {
let _ = setpgid(Pid::from_raw(0), Pid::from_raw(0));
Ok(())
}).spawn()?
})
.spawn()?
};
let mut stdout_lines = BufReader::new(handle.stdout.take().unwrap()).lines();
let mut stderr_lines = BufReader::new(handle.stderr.take().unwrap()).lines();
@ -268,7 +273,19 @@ impl ListenVarHandler {
if let Some(completion_notify) = completion_notify {
completion_notify.completed().await;
}
});
Ok(())
}
.await;
if let Err(err) = result {
log::error!(
"[{}:{}] Error while executing listen-var command {}: {:?}",
::std::file!(),
::std::line!(),
&var.command,
err
);
}
});
}

View file

@ -2,16 +2,6 @@ use extend::ext;
use itertools::Itertools;
use std::fmt::Write;
#[macro_export]
macro_rules! try_logging_errors {
($context:expr => $code:block) => {{
let result: Result<_> = try { $code };
if let Err(err) = result {
log::error!("[{}:{}] Error while {}: {:?}", ::std::file!(), ::std::line!(), $context, err);
}
}};
}
#[macro_export]
macro_rules! print_result_err {
($context:expr, $result:expr $(,)?) => {{

View file

@ -116,6 +116,7 @@ fn calc_widget_lowest_preferred_dimension(widget: &gtk::Widget) -> (i32, i32) {
}
impl BinImpl for CircProgPriv {}
impl WidgetImpl for CircProgPriv {
// We overwrite preferred_* so that overflowing content from the children gets cropped
// We return min(child_width, child_height)
@ -154,7 +155,7 @@ impl WidgetImpl for CircProgPriv {
}
fn draw(&self, cr: &cairo::Context) -> Inhibit {
let res: Result<()> = try {
let res: Result<()> = (|| {
let value = *self.value.borrow();
let start_at = *self.start_at.borrow();
let thickness = *self.thickness.borrow();
@ -218,7 +219,8 @@ impl WidgetImpl for CircProgPriv {
cr.reset_clip();
cr.restore()?;
}
};
Ok(())
})();
if let Err(error) = res {
error_handling_ctx::print_error(error)

View file

@ -19,14 +19,14 @@ macro_rules! def_widget {
// If an attribute is explicitly marked as optional (? appended to type)
// the attribute will still show up here, as a `None` value. Otherwise, all values in this map
// will be `Some`.
let attr_map: Result<HashMap<eww_shared_util::AttrName, Option<simplexpr::SimplExpr>>> = try {
::maplit::hashmap! {
let attr_map: Result<HashMap<eww_shared_util::AttrName, Option<simplexpr::SimplExpr>>> = (|| {
Ok(::maplit::hashmap! {
$(
eww_shared_util::AttrName(::std::stringify!($attr_name).to_owned()) =>
def_widget!(@get_value $args, &::std::stringify!($attr_name).replace('_', "-"), $(? $($optional)?)? $(= $default)?)
),*
}
};
})
})();
// Only proceed if any attributes from this `prop` where actually provided
if let Ok(attr_map) = attr_map {

View file

@ -171,7 +171,7 @@ impl WidgetImpl for GraphPriv {
}
fn draw(&self, cr: &cairo::Context) -> Inhibit {
let res: Result<()> = try {
let res: Result<()> = (|| {
let history = &*self.history.borrow();
let extra_point = *self.extra_point.borrow();
@ -269,7 +269,8 @@ impl WidgetImpl for GraphPriv {
cr.reset_clip();
cr.restore()?;
};
Ok(())
})();
if let Err(error) = res {
error_handling_ctx::print_error(error)

View file

@ -122,7 +122,7 @@ impl ContainerImpl for TransformPriv {
impl BinImpl for TransformPriv {}
impl WidgetImpl for TransformPriv {
fn draw(&self, cr: &cairo::Context) -> Inhibit {
let res: Result<()> = try {
let res: Result<()> = (|| {
let rotate = *self.rotate.borrow();
let total_width = self.obj().allocated_width() as f64;
let total_height = self.obj().allocated_height() as f64;
@ -159,7 +159,8 @@ impl WidgetImpl for TransformPriv {
}
cr.restore()?;
};
Ok(())
})();
if let Err(error) = res {
error_handling_ctx::print_error(error)

View file

@ -145,7 +145,7 @@ pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: &gtk::Wi
let css_provider = gtk::CssProvider::new();
let css_provider2 = css_provider.clone();
let visible_result: Result<_> = try {
let visible_result: Result<_> = (|| {
let visible_expr = bargs.widget_use.attrs.attrs.get("visible").map(|x| x.value.as_simplexpr()).transpose()?;
if let Some(visible_expr) = visible_expr {
let visible = bargs.scope_graph.evaluate_simplexpr_in_scope(bargs.calling_scope, &visible_expr)?.as_bool()?;
@ -157,7 +157,8 @@ pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: &gtk::Wi
}
});
}
};
Ok(())
})();
if let Err(err) = visible_result {
error_handling_ctx::print_error(err);
}
@ -898,7 +899,7 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
prop(content: as_string) {
gtk_widget.children().iter().for_each(|w| gtk_widget.remove(w));
if !content.is_empty() {
let content_widget_use: DiagResult<_> = try {
let content_widget_use: DiagResult<_> = (||{
let ast = {
let mut yuck_files = error_handling_ctx::FILE_DATABASE.write().unwrap();
let (span, asts) = yuck_files.load_yuck_str("<literal-content>".to_string(), content)?;
@ -908,8 +909,8 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result<gtk::Box> {
yuck::parser::require_single_toplevel(span, asts)?
};
yuck::config::widget_use::WidgetUse::from_ast(ast)?
};
yuck::config::widget_use::WidgetUse::from_ast(ast)
})();
let content_widget_use = content_widget_use?;
// TODO a literal should create a new scope, that I'm not even sure should inherit from root

View file

@ -1,6 +1,3 @@
#![feature(try_blocks)]
#![feature(unwrap_infallible)]
pub mod ast;
pub mod dynval;
pub mod error;

View file

@ -61,7 +61,7 @@ impl FromAstElementContent for PollScriptVar {
const ELEMENT_NAME: &'static str = "defpoll";
fn from_tail<I: Iterator<Item = Ast>>(_span: Span, mut iter: AstIterator<I>) -> DiagResult<Self> {
let result: DiagResult<_> = try {
let result: DiagResult<_> = (move || {
let (name_span, name) = iter.expect_symbol()?;
let mut attrs = iter.expect_key_values()?;
let initial_value = Some(attrs.primitive_optional("initial")?.unwrap_or_else(|| DynVal::from_string(String::new())));
@ -73,15 +73,15 @@ impl FromAstElementContent for PollScriptVar {
attrs.ast_optional::<SimplExpr>("run-while")?.unwrap_or_else(|| SimplExpr::Literal(DynVal::from(true)));
iter.expect_done()?;
Self {
Ok(Self {
name_span,
name: VarName(name),
run_while_expr,
command: VarSource::Shell(script_span, script.to_string()),
initial_value,
interval,
}
};
})
})();
result.note(r#"Expected format: `(defpoll name :interval "10s" "echo 'a shell script'")`"#)
}
}
@ -98,14 +98,14 @@ impl FromAstElementContent for ListenScriptVar {
const ELEMENT_NAME: &'static str = "deflisten";
fn from_tail<I: Iterator<Item = Ast>>(_span: Span, mut iter: AstIterator<I>) -> DiagResult<Self> {
let result: DiagResult<_> = try {
let result: DiagResult<_> = (move || {
let (name_span, name) = iter.expect_symbol()?;
let mut attrs = iter.expect_key_values()?;
let initial_value = attrs.primitive_optional("initial")?.unwrap_or_else(|| DynVal::from_string(String::new()));
let (command_span, script) = iter.expect_literal()?;
iter.expect_done()?;
Self { name_span, name: VarName(name), command: script.to_string(), initial_value, command_span }
};
Ok(Self { name_span, name: VarName(name), command: script.to_string(), initial_value, command_span })
})();
result.note(r#"Expected format: `(deflisten name :initial "0" "tail -f /tmp/example")`"#)
}
}

View file

@ -17,12 +17,12 @@ impl FromAstElementContent for VarDefinition {
const ELEMENT_NAME: &'static str = "defvar";
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> DiagResult<Self> {
let result: DiagResult<_> = try {
let result = (move || {
let (_, name) = iter.expect_symbol()?;
let (_, initial_value) = iter.expect_literal()?;
iter.expect_done()?;
Self { name: VarName(name), initial_value, span }
};
Ok(Self { name: VarName(name), initial_value, span })
})();
result.note(r#"Expected format: `(defvar name "initial-value")`"#)
}
}

View file

@ -99,9 +99,9 @@ impl std::str::FromStr for AnchorPoint {
Ok(AnchorPoint { x: AnchorAlignment::CENTER, y: AnchorAlignment::CENTER })
} else {
let (first, second) = s.split_once(' ').ok_or_else(|| AnchorPointParseError::WrongFormat(s.to_string()))?;
let x_y_result: Result<_, EnumParseError> = try {
AnchorPoint { x: AnchorAlignment::from_x_alignment(first)?, y: AnchorAlignment::from_y_alignment(second)? }
};
let x_y_result: Result<_, EnumParseError> = (move || {
Ok(AnchorPoint { x: AnchorAlignment::from_x_alignment(first)?, y: AnchorAlignment::from_y_alignment(second)? })
})();
x_y_result.or_else(|_| {
Ok(AnchorPoint { x: AnchorAlignment::from_x_alignment(second)?, y: AnchorAlignment::from_y_alignment(first)? })
})

View file

@ -1,5 +1,4 @@
#![allow(clippy::comparison_chain)]
#![feature(try_blocks)]
pub mod ast_error;
pub mod config;