From 52ac617bab87b937239b288627f5a6cdd5b81da8 Mon Sep 17 00:00:00 2001 From: elkowar <5300871+elkowar@users.noreply.github.com> Date: Sat, 17 Feb 2024 12:59:41 +0100 Subject: [PATCH] =?UTF-8?q?Yeet=20try=5Fblocks=20=F0=9F=98=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/eww/src/app.rs | 273 +++++++++--------- crates/eww/src/main.rs | 1 - crates/eww/src/script_var_handler.rs | 49 +++- crates/eww/src/util.rs | 10 - .../eww/src/widgets/circular_progressbar.rs | 6 +- crates/eww/src/widgets/def_widget_macro.rs | 8 +- crates/eww/src/widgets/graph.rs | 5 +- crates/eww/src/widgets/transform.rs | 5 +- crates/eww/src/widgets/widget_definitions.rs | 11 +- crates/simplexpr/src/lib.rs | 3 - .../yuck/src/config/script_var_definition.rs | 14 +- crates/yuck/src/config/var_definition.rs | 6 +- crates/yuck/src/config/window_geometry.rs | 6 +- crates/yuck/src/lib.rs | 1 - 14 files changed, 202 insertions(+), 196 deletions(-) diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index a3bc918a8..8b13a671b 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -146,150 +146,148 @@ impl std::fmt::Debug for App { } impl App { - /// 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 => { - gtk::Window::set_interactive_debugging(true); - } - DaemonCommand::UpdateVars(mappings) => { - for (var_name, new_value) in mappings { - self.update_global_variable(var_name, new_value); - } + match event { + DaemonCommand::NoOp => {} + DaemonCommand::OpenInspector => { + gtk::Window::set_interactive_debugging(true); + } + DaemonCommand::UpdateVars(mappings) => { + for (var_name, new_value) in mappings { + self.update_global_variable(var_name, new_value); } - DaemonCommand::ReloadConfigAndCss(sender) => { - let mut errors = Vec::new(); - - let config_result = config::read_from_eww_paths(&self.paths); - if let Err(e) = config_result.and_then(|new_config| self.load_config(new_config)) { - errors.push(e) - } - match crate::config::scss::parse_scss_from_config(self.paths.get_config_dir()) { - Ok((file_id, css)) => { - if let Err(e) = self.load_css(file_id, &css) { - errors.push(anyhow!(e)); - } - } - Err(e) => { - errors.push(e); - } - } + } + DaemonCommand::ReloadConfigAndCss(sender) => { + let mut errors = Vec::new(); - sender.respond_with_error_list(errors)?; - } - DaemonCommand::KillServer => { - log::info!("Received kill command, stopping server!"); - self.stop_application(); + let config_result = config::read_from_eww_paths(&self.paths); + if let Err(e) = config_result.and_then(|new_config| self.load_config(new_config)) { + errors.push(e) } - DaemonCommand::CloseAll => { - log::info!("Received close command, closing all windows"); - for window_name in self.open_windows.keys().cloned().collect::>() { - self.close_window(&window_name)?; + match crate::config::scss::parse_scss_from_config(self.paths.get_config_dir()) { + Ok((file_id, css)) => { + if let Err(e) = self.load_css(file_id, &css) { + errors.push(anyhow!(e)); + } } - } - DaemonCommand::OpenMany { windows, args, should_toggle, sender } => { - let errors = windows - .iter() - .map(|w| { - let (config_name, id) = w; - if should_toggle && self.open_windows.contains_key(id) { - self.close_window(id) - } else { - log::debug!("Config: {}, id: {}", config_name, id); - let window_args = args - .iter() - .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, - )?) - } - }) - .filter_map(Result::err); - sender.respond_with_error_list(errors)?; - } - DaemonCommand::OpenWindow { - window_name, - instance_id, - pos, - size, - anchor, - screen: monitor, - should_toggle, - duration, - sender, - args, - } => { - let instance_id = instance_id.unwrap_or_else(|| window_name.clone()); - - let is_open = self.open_windows.contains_key(&instance_id); - - let result = if should_toggle && is_open { - self.close_window(&instance_id) - } else { - self.open_window(&WindowArguments { - instance_id, - window_name, - pos, - size, - monitor, - anchor, - duration, - args: args.unwrap_or_default().into_iter().collect(), - }) - }; - - sender.respond_with_result(result)?; - } - DaemonCommand::CloseWindows { windows, sender } => { - let errors = windows.iter().map(|window| self.close_window(window)).filter_map(Result::err); - sender.respond_with_error_list(errors)?; - } - DaemonCommand::PrintState { all, sender } => { - let scope_graph = self.scope_graph.borrow(); - let used_globals_names = scope_graph.currently_used_globals(); - let output = scope_graph - .global_scope() - .data - .iter() - .filter(|(key, _)| all || used_globals_names.contains(*key)) - .map(|(key, value)| format!("{}: {}", key, value)) - .join("\n"); - sender.send_success(output)? - } - DaemonCommand::GetVar { name, sender } => { - let scope_graph = &*self.scope_graph.borrow(); - let vars = &scope_graph.global_scope().data; - match vars.get(name.as_str()) { - Some(x) => sender.send_success(x.to_string())?, - None => sender.send_failure(format!("Variable not found \"{}\"", name))?, + Err(e) => { + errors.push(e); } } - DaemonCommand::ListWindows(sender) => { - let output = self.eww_config.get_windows().keys().join("\n"); - sender.send_success(output)? - } - DaemonCommand::ListActiveWindows(sender) => { - let output = self.open_windows.iter().map(|(id, window)| format!("{id}: {}", window.name)).join("\n"); - sender.send_success(output)? - } - DaemonCommand::PrintDebug(sender) => { - let output = format!("{:#?}", &self); - sender.send_success(output)? + + sender.respond_with_error_list(errors)?; + } + DaemonCommand::KillServer => { + log::info!("Received kill command, stopping server!"); + self.stop_application(); + } + DaemonCommand::CloseAll => { + log::info!("Received close command, closing all windows"); + for window_name in self.open_windows.keys().cloned().collect::>() { + self.close_window(&window_name)?; } - DaemonCommand::PrintGraph(sender) => sender.send_success(self.scope_graph.borrow().visualize())?, } - }; + DaemonCommand::OpenMany { windows, args, should_toggle, sender } => { + let errors = windows + .iter() + .map(|w| { + let (config_name, id) = w; + if should_toggle && self.open_windows.contains_key(id) { + self.close_window(id) + } else { + log::debug!("Config: {}, id: {}", config_name, id); + let window_args = args + .iter() + .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)?) + } + }) + .filter_map(Result::err); + sender.respond_with_error_list(errors)?; + } + DaemonCommand::OpenWindow { + window_name, + instance_id, + pos, + size, + anchor, + screen: monitor, + should_toggle, + duration, + sender, + args, + } => { + let instance_id = instance_id.unwrap_or_else(|| window_name.clone()); + + let is_open = self.open_windows.contains_key(&instance_id); + + let result = if should_toggle && is_open { + self.close_window(&instance_id) + } else { + self.open_window(&WindowArguments { + instance_id, + window_name, + pos, + size, + monitor, + anchor, + duration, + args: args.unwrap_or_default().into_iter().collect(), + }) + }; - if let Err(err) = result { - error_handling_ctx::print_error(err); + sender.respond_with_result(result)?; + } + DaemonCommand::CloseWindows { windows, sender } => { + let errors = windows.iter().map(|window| self.close_window(window)).filter_map(Result::err); + sender.respond_with_error_list(errors)?; + } + DaemonCommand::PrintState { all, sender } => { + let scope_graph = self.scope_graph.borrow(); + let used_globals_names = scope_graph.currently_used_globals(); + let output = scope_graph + .global_scope() + .data + .iter() + .filter(|(key, _)| all || used_globals_names.contains(*key)) + .map(|(key, value)| format!("{}: {}", key, value)) + .join("\n"); + sender.send_success(output)? + } + DaemonCommand::GetVar { name, sender } => { + let scope_graph = &*self.scope_graph.borrow(); + let vars = &scope_graph.global_scope().data; + match vars.get(name.as_str()) { + Some(x) => sender.send_success(x.to_string())?, + None => sender.send_failure(format!("Variable not found \"{}\"", name))?, + } + } + DaemonCommand::ListWindows(sender) => { + let output = self.eww_config.get_windows().keys().join("\n"); + sender.send_success(output)? + } + DaemonCommand::ListActiveWindows(sender) => { + let output = self.open_windows.iter().map(|(id, window)| format!("{id}: {}", window.name)).join("\n"); + sender.send_success(output)? + } + DaemonCommand::PrintDebug(sender) => { + let output = format!("{:#?}", &self); + sender.send_success(output)? + } + DaemonCommand::PrintGraph(sender) => sender.send_success(self.scope_graph.borrow().visualize())?, } + Ok(()) } /// Fully stop eww: @@ -375,7 +373,7 @@ impl App { 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 App { } 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 App { 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 = 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::().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())), diff --git a/crates/eww/src/main.rs b/crates/eww/src/main.rs index d76b6ac53..aac52a6f7 100644 --- a/crates/eww/src/main.rs +++ b/crates/eww/src/main.rs @@ -1,4 +1,3 @@ -#![feature(try_blocks)] #![allow(rustdoc::private_intra_doc_links)] extern crate gtk; diff --git a/crates/eww/src/script_var_handler.rs b/crates/eww/src/script_var_handler.rs index 91aa2010c..717d4d92a 100644 --- a/crates/eww/src/script_var_handler.rs +++ b/crates/eww/src/script_var_handler.rs @@ -33,7 +33,7 @@ pub fn init(evt_send: UnboundedSender) -> 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) -> 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,17 +237,18 @@ 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]) - .stdout(std::process::Stdio::piped()) - .stderr(std::process::Stdio::piped()) - .stdin(std::process::Stdio::null()) - .pre_exec(|| { - let _ = setpgid(Pid::from_raw(0), Pid::from_raw(0)); - Ok(()) - }).spawn()? + .args(["-c", &var.command]) + .stdout(std::process::Stdio::piped()) + .stderr(std::process::Stdio::piped()) + .stdin(std::process::Stdio::null()) + .pre_exec(|| { + let _ = setpgid(Pid::from_raw(0), Pid::from_raw(0)); + Ok(()) + }) + .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 + ); + } }); } diff --git a/crates/eww/src/util.rs b/crates/eww/src/util.rs index fb5ae1674..b20fc2e9b 100644 --- a/crates/eww/src/util.rs +++ b/crates/eww/src/util.rs @@ -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 $(,)?) => {{ diff --git a/crates/eww/src/widgets/circular_progressbar.rs b/crates/eww/src/widgets/circular_progressbar.rs index 3975a21bf..76861afcd 100644 --- a/crates/eww/src/widgets/circular_progressbar.rs +++ b/crates/eww/src/widgets/circular_progressbar.rs @@ -116,6 +116,7 @@ fn calc_widget_lowest_preferred_dimension(widget: >k::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) diff --git a/crates/eww/src/widgets/def_widget_macro.rs b/crates/eww/src/widgets/def_widget_macro.rs index 282802970..311ce6f85 100644 --- a/crates/eww/src/widgets/def_widget_macro.rs +++ b/crates/eww/src/widgets/def_widget_macro.rs @@ -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>> = try { - ::maplit::hashmap! { + let attr_map: Result>> = (|| { + 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 { diff --git a/crates/eww/src/widgets/graph.rs b/crates/eww/src/widgets/graph.rs index 463c8bcd8..a3a77135a 100644 --- a/crates/eww/src/widgets/graph.rs +++ b/crates/eww/src/widgets/graph.rs @@ -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) diff --git a/crates/eww/src/widgets/transform.rs b/crates/eww/src/widgets/transform.rs index 6474416c0..faa9aa466 100644 --- a/crates/eww/src/widgets/transform.rs +++ b/crates/eww/src/widgets/transform.rs @@ -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) diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index 0166ba5e4..60fdb6f91 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -145,7 +145,7 @@ pub(super) fn resolve_widget_attrs(bargs: &mut BuilderArgs, gtk_widget: >k::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: >k::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 { 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("".to_string(), content)?; @@ -908,8 +909,8 @@ fn build_gtk_literal(bargs: &mut BuilderArgs) -> Result { 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 diff --git a/crates/simplexpr/src/lib.rs b/crates/simplexpr/src/lib.rs index f2d688cba..7f7c6b9e0 100644 --- a/crates/simplexpr/src/lib.rs +++ b/crates/simplexpr/src/lib.rs @@ -1,6 +1,3 @@ -#![feature(try_blocks)] -#![feature(unwrap_infallible)] - pub mod ast; pub mod dynval; pub mod error; diff --git a/crates/yuck/src/config/script_var_definition.rs b/crates/yuck/src/config/script_var_definition.rs index 1c77dda84..8686ab7ac 100644 --- a/crates/yuck/src/config/script_var_definition.rs +++ b/crates/yuck/src/config/script_var_definition.rs @@ -61,7 +61,7 @@ impl FromAstElementContent for PollScriptVar { const ELEMENT_NAME: &'static str = "defpoll"; fn from_tail>(_span: Span, mut iter: AstIterator) -> DiagResult { - 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::("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>(_span: Span, mut iter: AstIterator) -> DiagResult { - 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")`"#) } } diff --git a/crates/yuck/src/config/var_definition.rs b/crates/yuck/src/config/var_definition.rs index be4ab8d2e..95f7c8633 100644 --- a/crates/yuck/src/config/var_definition.rs +++ b/crates/yuck/src/config/var_definition.rs @@ -17,12 +17,12 @@ impl FromAstElementContent for VarDefinition { const ELEMENT_NAME: &'static str = "defvar"; fn from_tail>(span: Span, mut iter: AstIterator) -> DiagResult { - 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")`"#) } } diff --git a/crates/yuck/src/config/window_geometry.rs b/crates/yuck/src/config/window_geometry.rs index 07b221d62..9101af0d7 100644 --- a/crates/yuck/src/config/window_geometry.rs +++ b/crates/yuck/src/config/window_geometry.rs @@ -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)? }) }) diff --git a/crates/yuck/src/lib.rs b/crates/yuck/src/lib.rs index b6d4cc6b6..a754a7382 100644 --- a/crates/yuck/src/lib.rs +++ b/crates/yuck/src/lib.rs @@ -1,5 +1,4 @@ #![allow(clippy::comparison_chain)] -#![feature(try_blocks)] pub mod ast_error; pub mod config;