Yeet try_blocks 😢
This commit is contained in:
parent
0eed19332b
commit
60ab81ac13
14 changed files with 211 additions and 205 deletions
|
@ -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())),
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(try_blocks)]
|
||||
#![allow(rustdoc::private_intra_doc_links)]
|
||||
|
||||
extern crate gtk;
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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 $(,)?) => {{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<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
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
#![feature(try_blocks)]
|
||||
#![feature(unwrap_infallible)]
|
||||
|
||||
pub mod ast;
|
||||
pub mod dynval;
|
||||
pub mod error;
|
||||
|
|
|
@ -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")`"#)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")`"#)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)? })
|
||||
})
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#![allow(clippy::comparison_chain)]
|
||||
#![feature(try_blocks)]
|
||||
|
||||
pub mod ast_error;
|
||||
pub mod config;
|
||||
|
|
Loading…
Add table
Reference in a new issue