style: enable clippy::map_unwrap_or

Use `map_or`, `map_or_else`, `is_some_and`, and `is_ok_and` instead of
`map(..).unwrap_or(..)`.

Mostly mechanical, with the lint enabled in Cargo.toml:

    cargo clippy --fix --workspace --all-targets --all-features
    cargo clippy --fix --workspace --all-targets --no-default-features
    cargo fmt --all

Written by hand:
- The four caret-movement arms in caret_edit.rs are a `match`. The
  `map_or_else` form needs `caret` and `anchor` mutably in both
  closures.
- `sub_ring_children` is a `match`: the `&[]` default does not infer
  as a slice in `map_or`.
- The configurator's recorded-device mapping matches on
  `Option<InputSource>` directly, instead of a `map_or` with a nested
  `match`.

The translations guard lists the `tr(...)` arguments it accepts without
a literal as source text, so its two action-metadata entries follow the
new spelling.
This commit is contained in:
devmobasa committed 2026-10-26 12:46:35 +01:00
1 parent 85d0c9804b
commit 9c4336c645
104 files changed
+347 -473

No files matched your search

+1
View File
@@ -35,6 +35,7 @@ wildcard_imports = "warn"
# Pedantic lints, adopted one at a time. Most of them have machine-applicable
# fixes, so `cargo clippy --fix` can apply them.
cast_lossless = "warn"
map_unwrap_or = "warn"
uninlined_format_args = "warn"
[lints]
@@ -101,8 +101,7 @@ fn read_light_controls_status_from_config_root(config_root: &Path) -> HyprlandLi
let main_config_path = main_config_path(config_root);
let source_line = source_line_for_include(&include_path);
let source_present = fs::read_to_string(&main_config_path)
.map(|content| has_source_line(&content, &source_line))
.unwrap_or(false);
.is_ok_and(|content| has_source_line(&content, &source_line));
HyprlandLightControlsStatus {
include_exists: include_path.exists(),
@@ -327,9 +326,7 @@ fn strip_matching_quotes(value: &str) -> &str {
fn normalize_source_target(target: &str) -> PathBuf {
let expanded = if let Some(stripped) = target.strip_prefix("~/") {
paths::home_dir()
.map(|home| home.join(stripped))
.unwrap_or_else(|| PathBuf::from(target))
paths::home_dir().map_or_else(|| PathBuf::from(target), |home| home.join(stripped))
} else {
PathBuf::from(target)
};
+1 -3
View File
@@ -135,9 +135,7 @@ pub(super) fn install_or_update_user_service() -> Result<PathBuf, String> {
}
pub(super) fn detect_managed_daemon_portal_runtime_supported() -> bool {
managed_daemon_runtime_capabilities()
.map(|capabilities| capabilities.portal)
.unwrap_or(false)
managed_daemon_runtime_capabilities().is_ok_and(|capabilities| capabilities.portal)
}
fn managed_daemon_runtime_capabilities() -> Result<RuntimeCapabilities, String> {
+4 -4
View File
@@ -60,10 +60,10 @@ impl DaemonFeedback {
trf("Background setup action failed: {}", &[error])
}
Self::Action(ActionFeedback::RefreshFailed { previous, error }) => {
let previous = previous
.as_deref()
.map(DaemonFeedback::text)
.unwrap_or_else(|| tr("Background setup action failed.").to_string());
let previous = previous.as_deref().map_or_else(
|| tr("Background setup action failed.").to_string(),
DaemonFeedback::text,
);
trf("{}\nStatus refresh failed: {}", &[&previous, error])
}
}
+3 -3
View File
@@ -233,9 +233,9 @@ pub(super) fn light_controls_group(
None => set_visible(&path_label, false),
}
let capability = status
.map(|status| status.light_shortcut_apply_capability)
.unwrap_or(LightShortcutApplyCapability::Manual);
let capability = status.map_or(LightShortcutApplyCapability::Manual, |status| {
status.light_shortcut_apply_capability
});
let native = capability == LightShortcutApplyCapability::HyprlandNative;
set_visible(&native_body, native);
set_visible(&manual_label, !native);
@@ -222,16 +222,13 @@ fn attach_button_controller(popover: &gtk::Popover, sender: &ComponentSender<Con
let Some(button_event) = event.downcast_ref::<ButtonEvent>() else {
return Propagation::Proceed;
};
let kind = event
.device()
.map(|device| match device.source() {
InputSource::Mouse | InputSource::Touchpad | InputSource::Trackpoint => {
RecorderDeviceKind::Mouse
}
InputSource::Pen => RecorderDeviceKind::Pen,
_ => RecorderDeviceKind::Other,
})
.unwrap_or(RecorderDeviceKind::Other);
let kind = match event.device().map(|device| device.source()) {
Some(InputSource::Mouse | InputSource::Touchpad | InputSource::Trackpoint) => {
RecorderDeviceKind::Mouse
}
Some(InputSource::Pen) => RecorderDeviceKind::Pen,
_ => RecorderDeviceKind::Other,
};
let modifiers = event.modifier_state();
let recorded = KeyboardModifiers {
ctrl: modifiers.contains(ModifierType::CONTROL_MASK),
@@ -268,7 +268,7 @@ pub(super) fn binding_row(
.shortcuts
.editor()
.filter(|editor| editor.field == field);
let editor_text = editing.map(|editor| editor.text.as_str()).unwrap_or(value);
let editor_text = editing.map_or(value, |editor| editor.text.as_str());
let editor_error = editing.and_then(|editor| editor.parse_error());
text_editor.refresh(editing.is_some(), editor_text, editor_error.as_deref());
+1 -1
View File
@@ -7,7 +7,7 @@ fn clamp01(value: f64) -> f64 {
}
fn parse_component(value: &str, fallback: f64) -> f64 {
value.trim().parse::<f64>().map(clamp01).unwrap_or(fallback)
value.trim().parse::<f64>().map_or(fallback, clamp01)
}
pub fn parse_triplet_values(values: &[String; 3]) -> [f64; 3] {
@@ -134,8 +134,7 @@ fn resolved_label(label: &str, index: usize) -> String {
let trimmed = label.trim();
if trimmed.is_empty() {
QuickColorSlot::from_index(index)
.map(QuickColorSlot::label)
.unwrap_or("Quick color")
.map_or("Quick color", QuickColorSlot::label)
.to_string()
} else {
trimmed.to_string()
@@ -24,8 +24,9 @@ impl<'draft> ParsedShortcuts<'draft> {
self.entries
.iter()
.find(|(candidate, _)| *candidate == field)
.map(|(_, parsed)| parsed.as_ref().map(Vec::as_slice).map_err(String::as_str))
.unwrap_or(Ok(&[]))
.map_or(Ok(&[]), |(_, parsed)| {
parsed.as_ref().map(Vec::as_slice).map_err(String::as_str)
})
}
pub(super) fn claimants(&self, binding: &Shortcut) -> Vec<ShortcutClaim> {
+5 -7
View File
@@ -256,9 +256,7 @@ impl SessionCatalogItem {
}
fn optional_catalog_time(epoch_millis: Option<u64>) -> String {
epoch_millis
.map(format_catalog_time)
.unwrap_or_else(|| tr("Never").to_string())
epoch_millis.map_or_else(|| tr("Never").to_string(), format_catalog_time)
}
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -391,10 +389,10 @@ fn default_sibling_target_path(path: &Path, suffix_word: &str) -> PathBuf {
.and_then(|name| name.to_str())
.filter(|name| !name.is_empty())
.unwrap_or("session.wayscriber-session");
let target_name = file_name
.strip_suffix(SESSION_SUFFIX)
.map(|stem| format!("{stem} {suffix_word}{SESSION_SUFFIX}"))
.unwrap_or_else(|| format!("{file_name} {suffix_word}"));
let target_name = file_name.strip_suffix(SESSION_SUFFIX).map_or_else(
|| format!("{file_name} {suffix_word}"),
|stem| format!("{stem} {suffix_word}{SESSION_SUFFIX}"),
);
match path
.parent()
+2 -4
View File
@@ -20,14 +20,12 @@ impl WindowHandler for AboutWindowState {
let width = configure
.new_size
.0
.map(|w| w.get())
.unwrap_or(preferred_width)
.map_or(preferred_width, |w| w.get())
.max(1);
let height = configure
.new_size
.1
.map(|h| h.get())
.unwrap_or(preferred_height)
.map_or(preferred_height, |h| h.get())
.max(1);
if self.width != width || self.height != height {
@@ -367,8 +367,10 @@ fn handle_capture_worker_failure(
state.capture.finish_capture_lifecycle();
let message = operation
.filter(|operation| *operation == ImageOperationKind::Screenshot)
.map(|_| friendly_capture_error(CaptureFailureKind::Other))
.unwrap_or_else(|| "Capture services stopped unexpectedly.".to_string());
.map_or_else(
|| "Capture services stopped unexpectedly.".to_string(),
|_| friendly_capture_error(CaptureFailureKind::Other),
);
warn!("Board region capture worker failed: {error}");
state
.input_state
@@ -702,8 +704,7 @@ fn handle_capture_manager_failure(
notification::send_notification_async(
&state.tokio_handle,
operation
.map(ImageOperationKind::failure_title)
.unwrap_or(tr("Capture failed"))
.map_or(tr("Capture failed"), ImageOperationKind::failure_title)
.to_string(),
message,
Some("dialog-error".to_string()),
@@ -363,8 +363,7 @@ fn refused_drawings_options(options: &session::SessionOptions) -> session::Sessi
.unwrap_or_default();
let mut name = path
.file_stem()
.map(OsStr::to_os_string)
.unwrap_or_else(|| "session".into());
.map_or_else(|| "session".into(), OsStr::to_os_string);
name.push(format!(".unsaved-{millis}.wayscriber-session"));
let parent = path
.parent()
@@ -267,9 +267,10 @@ fn suggested_limit_mb(projected_written_size: u64, current_limit_bytes: u64) ->
}
fn config_path_display() -> String {
Config::config_path()
.map(|path| path.display().to_string())
.unwrap_or_else(|_| "~/.config/wayscriber/config.toml".to_string())
Config::config_path().map_or_else(
|_| "~/.config/wayscriber/config.toml".to_string(),
|path| path.display().to_string(),
)
}
#[cfg(test)]
+11 -15
View File
@@ -56,11 +56,9 @@ pub(super) fn poll_with_retry<T>(
loop {
match attempt(timeout_ms) {
Err(err) if err.kind() == io::ErrorKind::Interrupted => {
timeout_ms = deadline
.map(|deadline| {
timeout_to_poll_ms(Some(deadline.saturating_duration_since(Instant::now())))
})
.unwrap_or(-1);
timeout_ms = deadline.map_or(-1, |deadline| {
timeout_to_poll_ms(Some(deadline.saturating_duration_since(Instant::now())))
});
}
result => return result,
}
@@ -159,16 +157,14 @@ impl RuntimeWakeSource {
}
pub(super) fn timeout_to_poll_ms(timeout: Option<Duration>) -> i32 {
timeout
.map(|duration| {
// poll(2) accepts integer milliseconds. Round positive fractions
// up so an unexpired deadline never becomes a zero-timeout spin.
duration
.as_nanos()
.div_ceil(1_000_000)
.min(i32::MAX as u128) as i32
})
.unwrap_or(-1)
timeout.map_or(-1, |duration| {
// poll(2) accepts integer milliseconds. Round positive fractions
// up so an unexpired deadline never becomes a zero-timeout spin.
duration
.as_nanos()
.div_ceil(1_000_000)
.min(i32::MAX as u128) as i32
})
}
impl RuntimeWakeHandle {
@@ -407,9 +407,10 @@ fn keybinding_notification_body(entries: &[String], closing: &str) -> String {
}
fn config_path_display() -> String {
Config::config_path()
.map(|path| path.display().to_string())
.unwrap_or_else(|_| "~/.config/wayscriber/config.toml".to_string())
Config::config_path().map_or_else(
|_| "~/.config/wayscriber/config.toml".to_string(),
|path| path.display().to_string(),
)
}
fn log_config(config: &Config) {
@@ -23,16 +23,16 @@ pub(super) fn resolve(config: &Config) -> OutputPreferences {
let mut xdg_fullscreen = env::var(XDG_FULLSCREEN_ENV)
.ok()
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
.unwrap_or(config.ui.xdg_fullscreen);
.map_or(config.ui.xdg_fullscreen, |v| {
v == "1" || v.eq_ignore_ascii_case("true")
});
let desktop_env = env::var(XDG_CURRENT_DESKTOP_ENV).unwrap_or_default();
let session_env = env::var(XDG_SESSION_DESKTOP_ENV).unwrap_or_default();
let desktop_session = env::var(DESKTOP_SESSION_ENV).unwrap_or_default();
let sway_sock = env::var(SWAYSOCK_ENV).unwrap_or_default();
let niri_socket = env::var(NIRI_SOCKET_ENV).unwrap_or_default();
let force_fullscreen = env::var(XDG_FULLSCREEN_FORCE_ENV)
.map(|v| v == "1" || v.eq_ignore_ascii_case("true"))
.unwrap_or(false);
.is_ok_and(|v| v == "1" || v.eq_ignore_ascii_case("true"));
if xdg_fullscreen && desktop_env.to_uppercase().contains("GNOME") && !force_fullscreen {
warn!(
"GNOME fullscreen xdg fallback is opaque; falling back to maximized. Set {XDG_FULLSCREEN_FORCE_ENV}=1 to force fullscreen anyway."
+4 -5
View File
@@ -172,11 +172,10 @@ pub(in crate::backend::wayland) fn resolve_system_clipboard() -> ClipboardPasteR
);
if mime_type == WAYSCRIBER_SELECTION_MIME {
return serde_json::from_slice::<WayscriberClipboardSelection>(&bytes)
.map(ClipboardPasteResult::PrivateSelection)
.unwrap_or_else(|err| {
ClipboardPasteResult::MalformedPrivateSelection(err.to_string())
});
return serde_json::from_slice::<WayscriberClipboardSelection>(&bytes).map_or_else(
|err| ClipboardPasteResult::MalformedPrivateSelection(err.to_string()),
ClipboardPasteResult::PrivateSelection,
);
}
if file_list::is_uri_list_mime(&mime_type) {
+2 -3
View File
@@ -293,9 +293,8 @@ impl FrozenState {
WEnum::Value(v) => v.bits(),
WEnum::Unknown(raw) => raw,
};
capture.y_invert = Flags::from_bits(raw_flags)
.map(|f| f.contains(Flags::YInvert))
.unwrap_or(false);
capture.y_invert =
Flags::from_bits(raw_flags).is_some_and(|f| f.contains(Flags::YInvert));
}
}
FrameEvent::Ready { .. } => match self.on_ready() {
+3 -2
View File
@@ -71,8 +71,9 @@ impl DirectCaptureContext {
pub(super) fn timeout(&self, now: Instant) -> Duration {
self.started_at
.checked_add(DIRECT_CAPTURE_TIMEOUT)
.map(|deadline| deadline.saturating_duration_since(now))
.unwrap_or(Duration::ZERO)
.map_or(Duration::ZERO, |deadline| {
deadline.saturating_duration_since(now)
})
}
}
@@ -377,8 +377,7 @@ fn input_hud_button_label(button: u32) -> String {
BTN_RIGHT => tr("Right Click").to_string(),
BTN_MIDDLE => tr("Middle Click").to_string(),
other => linux::pointer_button(other)
.map(|button| button.name())
.unwrap_or_else(|| trf("Button {}", &[&other])),
.map_or_else(|| trf("Button {}", &[&other]), |button| button.name()),
}
}
+2 -4
View File
@@ -59,13 +59,11 @@ impl WindowHandler for WaylandState {
let width = configure
.new_size
.0
.map(|w| w.get())
.unwrap_or(fallback_dimensions.0);
.map_or(fallback_dimensions.0, |w| w.get());
let height = configure
.new_size
.1
.map(|h| h.get())
.unwrap_or(fallback_dimensions.1);
.map_or(fallback_dimensions.1, |h| h.get());
if self.surface.placement().xdg_frozen().requested() {
if let Some(output) = self.preferred_fullscreen_output() {
+4 -4
View File
@@ -50,8 +50,7 @@ impl<T: Send + 'static> PortalOperation<T> {
pub(super) fn poll(&mut self) -> PortalPoll<T> {
self.active
.as_mut()
.map(PortalTask::poll)
.unwrap_or(PortalPoll::Disconnected)
.map_or(PortalPoll::Disconnected, PortalTask::poll)
}
pub(super) fn timeout(&self, now: Instant) -> Option<Duration> {
self.active.as_ref().map(|task| task.timeout(now))
@@ -142,8 +141,9 @@ where
pub(super) fn timeout(&self, now: Instant) -> Duration {
self.started_at
.checked_add(PORTAL_CAPTURE_TIMEOUT)
.map(|deadline| deadline.saturating_duration_since(now))
.unwrap_or(Duration::ZERO)
.map_or(Duration::ZERO, |deadline| {
deadline.saturating_duration_since(now)
})
}
pub(super) fn timed_out(&self, now: Instant) -> bool {
@@ -430,10 +430,10 @@ fn describe_limit(limit: session::SaveLimitExceeded) -> String {
}
fn config_path_display() -> String {
Config::config_path()
.as_deref()
.map(compact_path)
.unwrap_or_else(|_| "~/.config/wayscriber/config.toml".to_string())
Config::config_path().as_deref().map_or_else(
|_| "~/.config/wayscriber/config.toml".to_string(),
compact_path,
)
}
fn compact_path(path: &Path) -> String {
@@ -11,8 +11,7 @@ impl WaylandState {
if let Some(preferred) = self.surface.placement().preferred_output_identity()
&& let Some(output) = self.protocol.output().outputs().find(|output| {
self.output_identity_for(output)
.map(|id| id.eq_ignore_ascii_case(preferred))
.unwrap_or(false)
.is_some_and(|id| id.eq_ignore_ascii_case(preferred))
})
{
return Some(output);
+1 -2
View File
@@ -407,8 +407,7 @@ fn log_frame_pacing_summary(summary: &PerfFramePacingSummary, final_summary: boo
fn perf_log_enabled_from_env() -> bool {
env::var(PERF_LOG_ENV)
.map(|value| matches!(value.trim(), "1" | "true" | "TRUE" | "yes" | "on" | "ON"))
.unwrap_or(false)
.is_ok_and(|value| matches!(value.trim(), "1" | "true" | "TRUE" | "yes" | "on" | "ON"))
}
fn duration_ms(duration: Duration) -> u64 {
@@ -188,8 +188,7 @@ impl WindowSnapSession {
}
let origin = self
.hovered_target()
.map(|target| rect_center(target.screen_rect))
.unwrap_or(pointer);
.map_or(pointer, |target| rect_center(target.screen_rect));
let current = self.hovered;
let mut best: Option<(usize, f64)> = None;
// Reverse provider order makes the visually topmost target win an
@@ -300,8 +300,7 @@ impl WaylandState {
);
let (hover_mx, hover_my) = self
.stylus_hover_cursor_position()
.map(|(x, y)| self.canvas_world_coords(x, y))
.unwrap_or((mx, my));
.map_or((mx, my), |(x, y)| self.canvas_world_coords(x, y));
self.render_eraser_hover_halos(ctx, hover_mx, hover_my);
+1 -3
View File
@@ -357,9 +357,7 @@ impl WaylandState {
);
self.input_state.set_toast_geometry(
toast_geometry.map(|geometry| geometry.0),
toast_geometry
.map(|geometry| geometry.1)
.unwrap_or([None, None]),
toast_geometry.map_or([None, None], |geometry| geometry.1),
);
ui::render_preset_toast_with_engine(
self.render.ui_text(),
@@ -74,8 +74,7 @@ pub(super) fn session_info_summary(inspection: &SessionInspection) -> String {
let size = inspection
.size_bytes
.map(format_byte_count)
.unwrap_or_else(|| tr("unknown size").to_string());
.map_or_else(|| tr("unknown size").to_string(), format_byte_count);
let shapes = inspection
.frame_counts
.map(|counts| {
@@ -119,10 +118,7 @@ fn recent_session_snapshots(current_path: Option<&Path>) -> Vec<SessionRecentSna
.into_iter()
.filter_map(|entry| {
let path = PathBuf::from(entry.path);
if current_path
.map(|current| catalog::session_paths_match(current, &path))
.unwrap_or(false)
{
if current_path.is_some_and(|current| catalog::session_paths_match(current, &path)) {
return None;
}
Some(SessionRecentSnapshot {
@@ -202,8 +202,7 @@ fn run_kdialog_session_file_dialog(
arguments.push(
current_path
.and_then(Path::parent)
.map(Path::to_path_buf)
.unwrap_or_else(default_session_dir)
.map_or_else(default_session_dir, Path::to_path_buf)
.into_os_string(),
);
}
+1 -2
View File
@@ -161,8 +161,7 @@ impl SurfaceState {
pub fn is_surface(&self, surface: &wl_surface::WlSurface) -> bool {
self.wl_surface
.as_ref()
.map(|current| current.id() == surface.id())
.unwrap_or(false)
.is_some_and(|current| current.id() == surface.id())
}
/// Returns the mutable layer surface, if initialized.
+3 -2
View File
@@ -42,8 +42,9 @@ impl XdgFrozenFullscreen {
Some(
self.requested_at
.and_then(|requested_at| requested_at.checked_add(XDG_FROZEN_FULLSCREEN_TIMEOUT))
.map(|deadline| deadline.saturating_duration_since(now))
.unwrap_or(Duration::ZERO),
.map_or(Duration::ZERO, |deadline| {
deadline.saturating_duration_since(now)
}),
)
}
+1 -5
View File
@@ -48,11 +48,7 @@ impl ToolbarSurfaceManager {
/// Store the latest snapshot and report whether it differs from the previous one.
pub fn update_snapshot(&mut self, snapshot: &ToolbarSnapshot) -> bool {
let changed = self
.last_snapshot
.as_ref()
.map(|prev| prev != snapshot)
.unwrap_or(true);
let changed = self.last_snapshot.as_ref() != Some(snapshot);
self.last_snapshot = Some(snapshot.clone());
changed
}
+3 -3
View File
@@ -55,9 +55,9 @@ pub fn paint_tree(
}
fn hovered(node: &WidgetNode, hover: Option<(f64, f64)>) -> bool {
hover
.map(|(hx, hy)| point_in_rect(hx, hy, node.rect.0, node.rect.1, node.rect.2, node.rect.3))
.unwrap_or(false)
hover.is_some_and(|(hx, hy)| {
point_in_rect(hx, hy, node.rect.0, node.rect.1, node.rect.2, node.rect.3)
})
}
fn label_style(size: f64, bold: bool) -> UiTextStyle<'static> {
@@ -68,8 +68,7 @@ impl ToolbarSurface {
pub fn is_layer(&self, layer: &LayerSurface) -> bool {
self.layer_surface
.as_ref()
.map(|ls| ls.wl_surface().id() == layer.wl_surface().id())
.unwrap_or(false)
.is_some_and(|ls| ls.wl_surface().id() == layer.wl_surface().id())
}
pub(in crate::backend::wayland) fn wl_surface(&self) -> Option<&wl_surface::WlSurface> {
@@ -79,8 +78,7 @@ impl ToolbarSurface {
pub fn is_surface(&self, surface: &wl_surface::WlSurface) -> bool {
self.wl_surface
.as_ref()
.map(|s| s.id() == surface.id())
.unwrap_or(false)
.is_some_and(|s| s.id() == surface.id())
}
/// Get cursor hint for the current hover position.
+8 -10
View File
@@ -1133,16 +1133,14 @@ fn preset_slot_node(
model::TopToolbarIcon::Tool(model::semantic_icon_for_tool(preset.tool)),
))
});
let color = preset
.map(|preset| {
(
preset.color.r,
preset.color.g,
preset.color.b,
preset.color.a,
)
})
.unwrap_or((0.0, 0.0, 0.0, 0.0));
let color = preset.map_or((0.0, 0.0, 0.0, 0.0), |preset| {
(
preset.color.r,
preset.color.g,
preset.color.b,
preset.color.a,
)
});
WidgetNode::new(
control.id().render_id().into_owned(),
rect,
@@ -724,8 +724,9 @@ fn settings_notice_height(engine: &UiTextEngine, text: &str, bold: bool) -> f64
};
engine
.measure(style, text, Some(MENU_CONTENT_W))
.map(|extents| extents.height() + MENU_NOTICE_PADDING_Y)
.unwrap_or(MENU_TOGGLE_H)
.map_or(MENU_TOGGLE_H, |extents| {
extents.height() + MENU_NOTICE_PADDING_Y
})
.max(MENU_TOGGLE_H)
}
+2 -3
View File
@@ -243,9 +243,8 @@ impl ZoomState {
WEnum::Value(v) => v.bits(),
WEnum::Unknown(raw) => raw,
};
capture.y_invert = Flags::from_bits(raw_flags)
.map(|f| f.contains(Flags::YInvert))
.unwrap_or(false);
capture.y_invert =
Flags::from_bits(raw_flags).is_some_and(|f| f.contains(Flags::YInvert));
}
}
FrameEvent::Ready { .. } => {
+3 -3
View File
@@ -315,9 +315,9 @@ pub fn resolve_pdf_page_layout(
};
let source_rect = match config.fit {
PdfFitMode::FitContentToPage => content_bounds
.map(|bounds| pad_source_rect(bounds, config.content_source_padding))
.unwrap_or(viewport_source),
PdfFitMode::FitContentToPage => content_bounds.map_or(viewport_source, |bounds| {
pad_source_rect(bounds, config.content_source_padding)
}),
PdfFitMode::FitViewportToPage | PdfFitMode::Viewport => viewport_source,
};
let (page_width, page_height) =
+3 -13
View File
@@ -188,9 +188,7 @@ pub fn action_meta(action: Action) -> Option<&'static ActionMeta> {
/// The untranslated label from the metadata table, falling back to a word for
/// actions that have no entry.
fn source_label(action: Action) -> &'static str {
action_meta(action)
.map(|meta| meta.label)
.unwrap_or("Action")
action_meta(action).map_or("Action", |meta| meta.label)
}
#[must_use]
@@ -200,11 +198,7 @@ pub fn action_label(action: Action) -> &'static str {
#[must_use]
pub fn action_short_label(action: Action) -> &'static str {
i18n::tr(
action_meta(action)
.map(|meta| meta.short_label())
.unwrap_or("Action"),
)
i18n::tr(action_meta(action).map_or("Action", |meta| meta.short_label()))
}
/// The compact spelling used where a full label is too wide.
@@ -232,11 +226,7 @@ pub fn action_display_label(action: Action) -> &'static str {
#[allow(dead_code)]
#[must_use]
pub fn action_description(action: Action) -> &'static str {
i18n::tr(
action_meta(action)
.map(|meta| meta.description)
.unwrap_or(""),
)
i18n::tr(action_meta(action).map_or("", |meta| meta.description))
}
#[cfg(test)]
+1 -2
View File
@@ -907,8 +907,7 @@ fn quick_color_label(entry: &QuickColorConfig, index: usize) -> String {
let trimmed = entry.label.trim();
if trimmed.is_empty() {
QuickColorSlot::from_index(index)
.map(QuickColorSlot::label)
.unwrap_or("Quick color")
.map_or("Quick color", QuickColorSlot::label)
.to_string()
} else {
trimmed.to_string()
+5 -6
View File
@@ -87,10 +87,10 @@ pub struct ToolPresetConfig {
impl ToolPresetConfig {
#[must_use]
pub fn preview_color_spec(&self) -> ColorSpec {
self.tool_settings
.as_ref()
.map(|settings| settings.color_spec_for_tool(self.tool))
.unwrap_or_else(|| self.color.clone())
self.tool_settings.as_ref().map_or_else(
|| self.color.clone(),
|settings| settings.color_spec_for_tool(self.tool),
)
}
#[must_use]
@@ -102,8 +102,7 @@ impl ToolPresetConfig {
pub fn preview_size(&self) -> f64 {
self.tool_settings
.as_ref()
.map(|settings| settings.size_for_tool(self.tool))
.unwrap_or(self.size)
.map_or(self.size, |settings| settings.size_for_tool(self.tool))
}
}
+1 -2
View File
@@ -76,8 +76,7 @@ impl Config {
.items
.iter()
.find(|item| item.background.is_transparent())
.map(|item| item.id.clone())
.unwrap_or_else(|| boards.items[0].id.clone());
.map_or_else(|| boards.items[0].id.clone(), |item| item.id.clone());
warn!(
"Default board '{}' not found; falling back to '{}'",
boards.default_board, fallback
+1 -2
View File
@@ -505,8 +505,7 @@ fn take_daemon_toggle_request_drains_multiple_payloads_in_order() {
assert!(
daemon_command_dir()
.read_dir()
.map(|mut entries| entries.next().is_none())
.unwrap_or(true)
.map_or(true, |mut entries| entries.next().is_none())
);
// SAFETY: this test still holds the environment mutex in `_guard`.
+1 -2
View File
@@ -576,7 +576,6 @@ fn owned_value_as_string(value: &OwnedValue) -> Option<String> {
fn make_handle_token(prefix: &str) -> String {
let nanos = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|duration| duration.as_nanos())
.unwrap_or(0);
.map_or(0, |duration| duration.as_nanos());
format!("{}_{}_{}", prefix, process::id(), nanos)
}
+1 -3
View File
@@ -296,9 +296,7 @@ pub(crate) fn gc_quarantine_tail(dir: &Path, retain: usize) -> io::Result<usize>
let excess = entries.len() - retain;
let mut removed = 0;
for (_, _, path) in entries.into_iter().take(excess) {
let is_dir = fs::symlink_metadata(&path)
.map(|metadata| metadata.is_dir())
.unwrap_or(false);
let is_dir = fs::symlink_metadata(&path).is_ok_and(|metadata| metadata.is_dir());
let result = if is_dir {
fs::remove_dir_all(&path)
} else {
+1 -2
View File
@@ -236,8 +236,7 @@ impl HistoryTrimStats {
pub(super) fn current_timestamp_ms() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|dur| dur.as_millis() as u64)
.unwrap_or(0)
.map_or(0, |dur| dur.as_millis() as u64)
}
#[cfg(test)]
+1 -2
View File
@@ -18,8 +18,7 @@ pub(crate) fn step_marker_radius_with(
let font_desc_str = font_descriptor.to_pango_string(size);
let max_dim = measurer
.measure(&text, &font_desc_str, size, None)
.map(|m| m.ink_width.max(m.ink_height))
.unwrap_or(size * 0.6);
.map_or(size * 0.6, |m| m.ink_width.max(m.ink_height));
let padding = (size * STEP_MARKER_PADDING_RATIO).max(STEP_MARKER_PADDING_MIN);
(max_dim / 2.0 + padding).max(STEP_MARKER_MIN_RADIUS)
}
+1 -1
View File
@@ -250,7 +250,7 @@ pub(crate) fn lookup(language: Language, source: &str) -> &str {
return source;
};
catalog.get(source).map(String::as_str).unwrap_or(source)
catalog.get(source).map_or(source, String::as_str)
}
/// Translates `source` and substitutes each `{}` with the next argument.
+18 -16
View File
@@ -204,22 +204,24 @@ fn pick_template(boards: &[BoardState]) -> BoardSpec {
let mut template = boards
.iter()
.find(|board| !board.spec.background.is_transparent())
.map(|board| board.spec.clone())
.unwrap_or_else(|| BoardSpec {
id: BOARD_ID_WHITEBOARD.to_string(),
name: "Whiteboard".to_string(),
background: BoardBackground::Solid(Color {
r: 0.992,
g: 0.992,
b: 0.992,
a: 1.0,
}),
grid: Default::default(),
default_pen_color: Some(PALETTE_BLACK),
auto_adjust_pen: true,
persist: true,
pinned: false,
});
.map_or_else(
|| BoardSpec {
id: BOARD_ID_WHITEBOARD.to_string(),
name: "Whiteboard".to_string(),
background: BoardBackground::Solid(Color {
r: 0.992,
g: 0.992,
b: 0.992,
a: 1.0,
}),
grid: Default::default(),
default_pen_color: Some(PALETTE_BLACK),
auto_adjust_pen: true,
persist: true,
pinned: false,
},
|board| board.spec.clone(),
);
template.pinned = false;
template
}
+2 -4
View File
@@ -88,8 +88,7 @@ impl InputState {
info!(
"Render profile {}",
self.active_render_profile()
.map(|profile| profile.name())
.unwrap_or("off")
.map_or("off", |profile| profile.name())
);
}
true
@@ -100,8 +99,7 @@ impl InputState {
info!(
"Render profile {}",
self.active_render_profile()
.map(|profile| profile.name())
.unwrap_or("off")
.map_or("off", |profile| profile.name())
);
}
true
+44 -51
View File
@@ -128,13 +128,13 @@ fn next_word_end(s: &str, caret: usize) -> usize {
/// Byte offset of the start of the logical line containing `caret`.
fn line_start(s: &str, caret: usize) -> usize {
s[..caret].rfind('\n').map(|i| i + 1).unwrap_or(0)
s[..caret].rfind('\n').map_or(0, |i| i + 1)
}
/// Byte offset of the end of the logical line containing `caret` (the position
/// of the next newline, or the buffer end).
fn line_end(s: &str, caret: usize) -> usize {
s[caret..].find('\n').map(|i| caret + i).unwrap_or(s.len())
s[caret..].find('\n').map_or(s.len(), |i| caret + i)
}
/// Grapheme count of `s` (used as the column metric for vertical movement).
@@ -146,8 +146,7 @@ fn grapheme_len(s: &str) -> usize {
fn grapheme_col_to_byte(s: &str, col: usize) -> usize {
s.grapheme_indices(true)
.nth(col)
.map(|(i, _)| i)
.unwrap_or(s.len())
.map_or(s.len(), |(i, _)| i)
}
/// Clamp `caret` and `anchor` to valid char boundaries within `buffer` (used
@@ -193,9 +192,7 @@ pub(in crate::input::state) fn insert_str(
text: &str,
max_len: usize,
) -> bool {
let selected_len = selection_range(*caret, *anchor)
.map(|range| range.len())
.unwrap_or(0);
let selected_len = selection_range(*caret, *anchor).map_or(0, |range| range.len());
let remaining = max_len.saturating_sub(buffer.len().saturating_sub(selected_len));
let mut fit = text.len().min(remaining);
while fit > 0 && !text.is_char_boundary(fit) {
@@ -557,52 +554,48 @@ impl TextEditing {
ctrl,
VisualCaretDirection::Right,
),
Key::Up => navigation
.measurer
.caret_on_adjacent_visual_line(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineDirection::Up,
)
.map(|new| move_to_offset(caret, anchor, shift, new))
.unwrap_or_else(|| move_up(buffer, caret, anchor, shift)),
Key::Down => navigation
.measurer
.caret_on_adjacent_visual_line(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineDirection::Down,
)
.map(|new| move_to_offset(caret, anchor, shift, new))
.unwrap_or_else(|| move_down(buffer, caret, anchor, shift)),
Key::Up => match navigation.measurer.caret_on_adjacent_visual_line(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineDirection::Up,
) {
Some(new) => move_to_offset(caret, anchor, shift, new),
None => move_up(buffer, caret, anchor, shift),
},
Key::Down => match navigation.measurer.caret_on_adjacent_visual_line(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineDirection::Down,
) {
Some(new) => move_to_offset(caret, anchor, shift, new),
None => move_down(buffer, caret, anchor, shift),
},
Key::Home if ctrl => move_document_start(caret, anchor, shift),
Key::Home => navigation
.measurer
.caret_on_visual_line_edge(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineEdge::Start,
)
.map(|new| move_to_offset(caret, anchor, shift, new))
.unwrap_or_else(|| move_line_home(buffer, caret, anchor, shift)),
Key::Home => match navigation.measurer.caret_on_visual_line_edge(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineEdge::Start,
) {
Some(new) => move_to_offset(caret, anchor, shift, new),
None => move_line_home(buffer, caret, anchor, shift),
},
Key::End if ctrl => move_document_end(buffer, caret, anchor, shift),
Key::End => navigation
.measurer
.caret_on_visual_line_edge(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineEdge::End,
)
.map(|new| move_to_offset(caret, anchor, shift, new))
.unwrap_or_else(|| move_line_end(buffer, caret, anchor, shift)),
Key::End => match navigation.measurer.caret_on_visual_line_edge(
buffer,
navigation.font,
navigation.wrap_width,
*caret,
VisualLineEdge::End,
) {
Some(new) => move_to_offset(caret, anchor, shift, new),
None => move_line_end(buffer, caret, anchor, shift),
},
_ => return None,
};
+5 -11
View File
@@ -293,8 +293,7 @@ impl InputState {
let remaining = self
.board_picker_page_panel_board_index()
.and_then(|bi| self.boards.board_states().get(bi))
.map(|b| b.pages.page_count())
.unwrap_or(0);
.map_or(0, |b| b.pages.page_count());
if remaining == 0 {
self.board_picker_set_focus(BoardPickerFocus::BoardList);
} else {
@@ -347,8 +346,7 @@ impl InputState {
let page_count = self
.board_picker_page_panel_board_index()
.and_then(|bi| self.boards.board_states().get(bi))
.map(|b| b.pages.page_count())
.unwrap_or(0);
.map_or(0, |b| b.pages.page_count());
let current = self
.board_picker_page_focus_page_index()
.unwrap_or_else(|| {
@@ -362,7 +360,7 @@ impl InputState {
fn navigate_board_picker_page_panel(&mut self, key: Key, page_count: usize, current: usize) {
let layout = self.board_picker.layout;
let page_cols = layout.map(|l| l.page_cols.max(1)).unwrap_or(1);
let page_cols = layout.map_or(1, |l| l.page_cols.max(1));
match key {
Key::Left if current == 0 => {
@@ -389,15 +387,11 @@ impl InputState {
self.board_picker_set_page_focus_page_index(page_count.saturating_sub(1));
}
Key::PageUp if page_count > 0 => {
let step = layout
.map(|l| l.page_visible_slots.max(page_cols))
.unwrap_or(page_cols);
let step = layout.map_or(page_cols, |l| l.page_visible_slots.max(page_cols));
self.board_picker_set_page_focus_page_index(current.saturating_sub(step));
}
Key::PageDown if page_count > 0 => {
let step = layout
.map(|l| l.page_visible_slots.max(page_cols))
.unwrap_or(page_cols);
let step = layout.map_or(page_cols, |l| l.page_visible_slots.max(page_cols));
let next = current
.saturating_add(step)
.min(page_count.saturating_sub(1));
+1 -1
View File
@@ -444,7 +444,7 @@ impl ToastPress {
}
pub(crate) fn matches_target(self, target: Option<usize>) -> bool {
self.target == target.map(ToastTarget::Action).unwrap_or(ToastTarget::Body)
self.target == target.map_or(ToastTarget::Body, ToastTarget::Action)
}
pub(crate) fn action_index(self) -> Option<usize> {
+4 -5
View File
@@ -126,11 +126,10 @@ impl InputState {
measurer: &TextMeasurer,
now: Instant,
) {
let request = self
.board_transitions
.confirm_board_delete(now)
.map(|pending| BoardDeleteRequest::Confirm(pending.confirmation().clone()))
.unwrap_or(BoardDeleteRequest::Request(BoardDeleteTarget::Active));
let request = self.board_transitions.confirm_board_delete(now).map_or(
BoardDeleteRequest::Request(BoardDeleteTarget::Active),
|pending| BoardDeleteRequest::Confirm(pending.confirmation().clone()),
);
let active_id_before = self.boards.active_board_id().to_string();
let current_spec = self.boards.active_board().spec.clone();
@@ -48,13 +48,15 @@ impl InputState {
let request = self
.board_transitions
.confirm_page_delete_for(now, &board_id, page_index)
.map(|pending| PageDeleteRequest::Confirm(pending.confirmation().clone()))
.unwrap_or_else(|| {
PageDeleteRequest::Request(PageDeleteTarget {
board: PageDeleteBoardTarget::BoardIndex(board_index),
page_index,
})
});
.map_or_else(
|| {
PageDeleteRequest::Request(PageDeleteTarget {
board: PageDeleteBoardTarget::BoardIndex(board_index),
page_index,
})
},
|pending| PageDeleteRequest::Confirm(pending.confirmation().clone()),
);
let confirmation_is_current = matches!(&request, PageDeleteRequest::Confirm(confirmation) if self.page_delete_confirmation_is_current(confirmation));
let should_prepare_active = is_active_board
&& ((matches!(&request, PageDeleteRequest::Request(_)) && page_count <= 1)
@@ -137,16 +139,15 @@ impl InputState {
let page_count = self.boards.page_count();
let page_index = self.boards.active_page_index();
let request = self
.board_transitions
.confirm_page_delete(now)
.map(|pending| PageDeleteRequest::Confirm(pending.confirmation().clone()))
.unwrap_or_else(|| {
let request = self.board_transitions.confirm_page_delete(now).map_or_else(
|| {
PageDeleteRequest::Request(PageDeleteTarget {
board: PageDeleteBoardTarget::ActiveBoard,
page_index,
})
});
},
|pending| PageDeleteRequest::Confirm(pending.confirmation().clone()),
);
let active_target = match &request {
PageDeleteRequest::Confirm(confirmation) => {
confirmation.board_id == self.boards.active_board_id()
@@ -82,9 +82,8 @@ impl InputState {
ctx.select_font_face("Sans", cairo::FontSlant::Normal, cairo::FontWeight::Normal);
ctx.set_font_size(config.footer_font_size);
let footer_width = text_width(ctx, footer, config.footer_font_size);
let recent_width = recent
.map(|label| text_width(ctx, label, config.footer_font_size))
.unwrap_or(0.0);
let recent_width =
recent.map_or(0.0, |label| text_width(ctx, label, config.footer_font_size));
(title_width, footer_width, recent_width)
}
@@ -20,8 +20,7 @@ impl InputState {
&& self
.board_picker_board_index_for_row(edit_index)
.and_then(|board_index| self.boards.board_states().get(board_index))
.map(|board| !board.spec.background.is_transparent())
.unwrap_or(false)
.is_some_and(|board| !board.spec.background.is_transparent())
{
let colors = board_palette_colors();
if !colors.is_empty() {
+2 -5
View File
@@ -68,10 +68,7 @@ impl InputState {
} else if name.contains(&lower) || id.contains(&lower) {
score += 500;
}
if best
.map(|(_, best_score)| score > best_score)
.unwrap_or(true)
{
if best.is_none_or(|(_, best_score)| score > best_score) {
best = Some((idx, score));
}
}
@@ -138,7 +135,7 @@ fn fuzzy_score_with_single_swap(needle: &str, haystack: &str) -> Option<i32> {
let swapped: String = chars.iter().collect();
if let Some(score) = fuzzy_score(&swapped, haystack) {
let score = score - 25;
if best.map(|best| score > best).unwrap_or(true) {
if best.is_none_or(|best| score > best) {
best = Some(score);
}
}
+4 -12
View File
@@ -152,9 +152,7 @@ impl TextEditing {
return None;
};
let caret = clamp_char_boundary(buffer, *caret);
let anchor = selection_anchor
.map(|anchor| clamp_char_boundary(buffer, anchor))
.unwrap_or(caret);
let anchor = selection_anchor.map_or(caret, |anchor| clamp_char_boundary(buffer, anchor));
surrounding_text_window(buffer, caret, anchor)
}
@@ -171,9 +169,7 @@ impl TextEditing {
return false;
};
let caret = clamp_char_boundary(buffer, *caret);
let anchor = selection_anchor
.map(|anchor| clamp_char_boundary(buffer, anchor))
.unwrap_or(caret);
let anchor = selection_anchor.map_or(caret, |anchor| clamp_char_boundary(buffer, anchor));
caret.abs_diff(anchor) <= MAX_SURROUNDING_TEXT_BYTES
}
@@ -270,12 +266,8 @@ impl TextEditing {
let selection = caret_edit::selection_range(original_caret, original_anchor);
let before_edge = selection
.as_ref()
.map(|range| range.start)
.unwrap_or(original_caret);
let after_edge = selection
.as_ref()
.map(|range| range.end)
.unwrap_or(original_caret);
.map_or(original_caret, |range| range.start);
let after_edge = selection.as_ref().map_or(original_caret, |range| range.end);
let mut start = before_edge.saturating_sub(pending.delete_before as usize);
while start > 0 && !buffer.is_char_boundary(start) {
start -= 1;
+2 -2
View File
@@ -14,11 +14,11 @@ impl InputState {
let frame = self.boards.active_frame();
let locked = ids
.iter()
.any(|id| frame.shape(*id).map(|shape| shape.locked).unwrap_or(false));
.any(|id| frame.shape(*id).is_some_and(|shape| shape.locked));
let all_locked = !ids.is_empty()
&& ids
.iter()
.all(|id| frame.shape(*id).map(|shape| shape.locked).unwrap_or(false));
.all(|id| frame.shape(*id).is_some_and(|shape| shape.locked));
// What a right-click on a shape is usually for comes first: its own
// editor, then its properties.
+2 -3
View File
@@ -106,10 +106,9 @@ impl InputState {
.boards
.active_frame()
.shape(selection[0])
.map(|shape| {
.is_some_and(|shape| {
matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. })
})
.unwrap_or(false);
});
let anchor = self.keyboard_shape_menu_anchor(measurer, &selection);
self.update_pointer_position_synthetic(anchor.0, anchor.1);
self.open_context_menu(anchor, selection, ContextMenuKind::Shape, None);
+1 -2
View File
@@ -32,8 +32,7 @@ fn summary_value<T: Clone>(
summary
.value
.clone()
.map(format)
.unwrap_or_else(|| tr("Mixed").to_string())
.map_or_else(|| tr("Mixed").to_string(), format)
}
/// The summary's single editable value, or `None` when it is mixed or locked:
@@ -12,18 +12,19 @@ mod layout;
mod tests;
pub(super) fn selection_panel_anchor(bounds: Option<Rect>, pointer: (i32, i32)) -> (f64, f64) {
bounds
.map(|rect| {
(
f64::from(rect.x) + f64::from(rect.width) + PANEL_ANCHOR_GAP,
(f64::from(rect.y) - PANEL_ANCHOR_GAP).max(PANEL_MARGIN),
)
})
.unwrap_or_else(|| {
bounds.map_or_else(
|| {
let (px, py) = pointer;
(
f64::from(px) + PANEL_POINTER_OFFSET,
f64::from(py) - PANEL_POINTER_OFFSET,
)
})
},
|rect| {
(
f64::from(rect.x) + f64::from(rect.width) + PANEL_ANCHOR_GAP,
(f64::from(rect.y) - PANEL_ANCHOR_GAP).max(PANEL_MARGIN),
)
},
)
}
+4 -3
View File
@@ -59,9 +59,10 @@ pub(super) fn palette_position(
/// The palette's name for `color`, or "Custom" for a color it does not hold.
pub(super) fn color_label(palette: &[QuickColorPaletteEntry], color: Color) -> String {
color_palette_index(palette, color)
.map(|index| palette[index].label.clone())
.unwrap_or_else(|| "Custom".to_string())
color_palette_index(palette, color).map_or_else(
|| "Custom".to_string(),
|index| palette[index].label.clone(),
)
}
pub(super) fn color_eq(a: &Color, b: &Color) -> bool {
+5 -3
View File
@@ -181,10 +181,12 @@ pub fn slice_parent(idx: u8) -> Option<RadialParent> {
}
/// Sub-ring children for a segment index (empty for non-parent slices).
#[must_use]
pub fn sub_ring_children(parent_idx: u8) -> &'static [Action] {
slice_parent(parent_idx)
.map(RadialParent::children)
.unwrap_or(&[])
match slice_parent(parent_idx) {
Some(parent) => parent.children(),
None => &[],
}
}
/// Number of sub-ring children for a segment index, or 0 if none.
+1 -2
View File
@@ -386,8 +386,7 @@ fn non_empty_shapes(shapes: Vec<Shape>) -> Option<Vec<Shape>> {
fn new_clipboard_app_instance_id() -> String {
let millis = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|duration| duration.as_millis())
.unwrap_or(0);
.map_or(0, |duration| duration.as_millis());
format!("{}-{millis}", process::id())
}
+1 -2
View File
@@ -153,8 +153,7 @@ impl SequenceTrie {
return SequenceMatch::None;
};
node.action
.map(SequenceMatch::Dispatched)
.unwrap_or(SequenceMatch::None)
.map_or(SequenceMatch::None, SequenceMatch::Dispatched)
}
}
@@ -331,8 +331,9 @@ fn open_context_menu_from_right_click(
.boards
.active_frame()
.shape(selection[0])
.map(|shape| matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. }))
.unwrap_or(false);
.is_some_and(|shape| {
matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. })
});
state.open_context_menu(
(screen_x, screen_y),
selection,
+4 -6
View File
@@ -76,10 +76,9 @@ impl InputState {
.boards
.active_frame()
.shape(selection[0])
.map(|shape| {
.is_some_and(|shape| {
matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. })
})
.unwrap_or(false);
});
self.open_context_menu(
(screen_x, screen_y),
selection,
@@ -515,11 +514,10 @@ impl InputState {
.boards
.active_frame()
.shape(hit_id)
.map(|shape| {
.is_some_and(|shape| {
!shape.locked
&& matches!(shape.shape, Shape::Text { .. } | Shape::StickyNote { .. })
})
.unwrap_or(false);
});
if is_text {
self.begin_pointer_drag(button, color);
self.state = DrawingState::PendingTextClick {
+7 -11
View File
@@ -196,17 +196,13 @@ pub(super) fn handle_board_picker_release(
return true;
}
let now = Instant::now();
let is_double = state
.board_picker
.last_click
.map(|last| {
last.row == index
&& now.duration_since(last.at).as_millis()
<= u128::from(BOARD_PICKER_DOUBLE_CLICK_MS)
&& (x - last.x).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE
&& (y - last.y).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE
})
.unwrap_or(false);
let is_double = state.board_picker.last_click.is_some_and(|last| {
last.row == index
&& now.duration_since(last.at).as_millis()
<= u128::from(BOARD_PICKER_DOUBLE_CLICK_MS)
&& (x - last.x).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE
&& (y - last.y).abs() <= BOARD_PICKER_DOUBLE_CLICK_DISTANCE
});
if is_double {
state.board_picker.last_click = None;
state.board_picker_activate_row_with_measurer(resources.measurer, index);
+1 -4
View File
@@ -100,10 +100,7 @@ fn clear_all_skips_locked_shapes() {
let frame = state.boards.active_frame();
assert!(frame.shape(unlocked_id).is_none());
assert!(
frame
.shape(locked_id)
.map(|shape| shape.locked)
.unwrap_or(false),
frame.shape(locked_id).is_some_and(|shape| shape.locked),
"locked shape should remain after clear_all"
);
}
+1 -2
View File
@@ -167,8 +167,7 @@ impl Drop for WritingRecord {
fn timestamp_millis() -> u128 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|duration| duration.as_millis())
.unwrap_or(0)
.map_or(0, |duration| duration.as_millis())
}
struct LogSink {
+3 -2
View File
@@ -44,8 +44,9 @@ fn resolve_log_max_bytes() -> u64 {
.ok()
.and_then(|value| value.trim().parse::<u64>().ok())
.filter(|value| *value > 0)
.map(|value| value.saturating_mul(BYTES_PER_MB))
.unwrap_or(DEFAULT_LOG_MAX_BYTES)
.map_or(DEFAULT_LOG_MAX_BYTES, |value| {
value.saturating_mul(BYTES_PER_MB)
})
}
fn current_log_date() -> String {
+1 -2
View File
@@ -238,8 +238,7 @@ fn program_in_search_path(program: &str, search_path: &OsStr) -> bool {
return false;
}
fs::metadata(directory.join(program))
.map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
.unwrap_or(false)
.is_ok_and(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
})
}
@@ -250,12 +250,11 @@ impl RuntimeUiStateController {
model: model.clone(),
passthrough: passthrough.clone(),
};
let (next_seeds, changed_targets, tombstoned_targets) = self
.staged_reload
.as_ref()
.cloned()
.map(StagedSeedReload::into_parts)
.unwrap_or_else(|| (self.seeds.clone(), BTreeSet::new(), BTreeSet::new()));
let (next_seeds, changed_targets, tombstoned_targets) =
self.staged_reload.as_ref().cloned().map_or_else(
|| (self.seeds.clone(), BTreeSet::new(), BTreeSet::new()),
StagedSeedReload::into_parts,
);
let mut canonical_model = model;
canonical_model.remove_targets(&tombstoned_targets);
canonical_model.reconcile(&next_seeds);
+1 -2
View File
@@ -364,8 +364,7 @@ impl RuntimeUiStateController {
let attempt = self
.active_recovery
.as_ref()
.map(|attempt| attempt.id)
.unwrap_or(RecoveryAttemptId(0));
.map_or(RecoveryAttemptId(0), |attempt| attempt.id);
let recovery = self.rotate_and_checkout_handle();
if let Some(barrier) = &mut self.active_barrier {
barrier.phase = ControllerBarrierPhase::PersistenceUnhealthy {
+2 -3
View File
@@ -102,9 +102,8 @@ impl StagedSeedReload {
current: &InteractionSeedRegistry,
seeds: &ValidatedInteractionSeeds,
) -> Result<Self, SeedRegistryError> {
let mut registry = previous
.map(|staged| staged.registry.clone())
.unwrap_or_else(|| current.clone());
let mut registry =
previous.map_or_else(|| current.clone(), |staged| staged.registry.clone());
let mut changed_targets = previous
.map(|staged| staged.changed_targets.clone())
.unwrap_or_default();
+5 -5
View File
@@ -233,9 +233,10 @@ impl CatalogFile {
let mut entry = CatalogEntry {
id: generated_catalog_id(now),
display_name: display_name
.map(str::to_string)
.unwrap_or_else(|| display_name_for_path(&identity.exact_path)),
display_name: display_name.map_or_else(
|| display_name_for_path(&identity.exact_path),
str::to_string,
),
path: path_to_string(&identity.exact_path)?,
canonical_path: optional_path_to_string(identity.canonical_path.as_deref())?,
created_at_millis: now,
@@ -444,8 +445,7 @@ fn generated_catalog_id(now: u64) -> String {
fn now_epoch_millis() -> u64 {
let millis = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|duration| duration.as_millis())
.unwrap_or(0);
.map_or(0, |duration| duration.as_millis());
u64::try_from(millis).unwrap_or(u64::MAX)
}
+1 -2
View File
@@ -230,8 +230,7 @@ impl SessionOptions {
pub(crate) fn session_file_parent_dir(path: &Path) -> PathBuf {
path.parent()
.filter(|parent| !parent.as_os_str().is_empty())
.map(Path::to_path_buf)
.unwrap_or_else(|| PathBuf::from("."))
.map_or_else(|| PathBuf::from("."), Path::to_path_buf)
}
pub(crate) fn append_path_suffix(path: &Path, suffix: &str) -> PathBuf {
+3 -3
View File
@@ -237,9 +237,9 @@ fn history_depth_from_pages(pages: Option<&BoardPagesSnapshot>) -> HistoryDepth
}
fn page_shape_count(pages: Option<&BoardPagesSnapshot>) -> usize {
pages
.map(|pages| pages.pages.iter().map(|page| page.shapes.len()).sum())
.unwrap_or(0)
pages.map_or(0, |pages| {
pages.pages.iter().map(|page| page.shapes.len()).sum()
})
}
fn find_existing_variant(
+1 -2
View File
@@ -92,8 +92,7 @@ pub fn render_user_service_unit(binary_path: &Path) -> String {
let quoted_exec = quote_systemd_exec(binary_path);
let binary_dir = binary_path
.parent()
.map(|path| path.display().to_string())
.unwrap_or_else(|| "/usr/bin".to_string());
.map_or_else(|| "/usr/bin".to_string(), |path| path.display().to_string());
// Prepended so an install outside the system directories still finds its
// own helpers first, and skipped when it is already one of them rather
// than emitting the directory twice.
+1 -2
View File
@@ -75,8 +75,7 @@ pub fn format_unix_millis(ms: u64, template: &str) -> Option<String> {
pub fn now_rfc3339() -> String {
system_time_to_unix_seconds(SystemTime::now())
.and_then(utc_datetime_from_unix)
.map(format_rfc3339_utc)
.unwrap_or_else(|| "1970-01-01T00:00:00Z".to_string())
.map_or_else(|| "1970-01-01T00:00:00Z".to_string(), format_rfc3339_utc)
}
fn push_padded_u8(out: &mut String, value: u8) {
@@ -166,8 +166,7 @@ fn builtin_semantic_records(
let lane = expected
.iter()
.find(|record| record_id(record) == raw_id)
.map(record_lane)
.unwrap_or(SemanticLane::Strip);
.map_or(SemanticLane::Strip, record_lane);
(lane, raw_id)
};
let Some(record) = expected
+2 -2
View File
@@ -143,7 +143,7 @@ impl SliderRow {
drag.connect_drag_begin(move |gesture, x, _| {
drag_state.dragging.set(true);
// Jump the knob to the pressed position, like the built-in track.
let width = f64::from(gesture.widget().map(|w| w.width()).unwrap_or(1).max(1));
let width = f64::from(gesture.widget().map_or(1, |w| w.width()).max(1));
let t = (x / width).clamp(0.0, 1.0);
let value = drag_state.spec.value_from_t(t);
drag_state.value.set(value);
@@ -159,7 +159,7 @@ impl SliderRow {
let change = Rc::new(on_change);
let update_change = change.clone();
drag.connect_drag_update(move |gesture, dx, _| {
let width = f64::from(gesture.widget().map(|w| w.width()).unwrap_or(1).max(1));
let width = f64::from(gesture.widget().map_or(1, |w| w.width()).max(1));
let (sx, _) = update_start.get();
let t = ((sx + dx) / width).clamp(0.0, 1.0);
let value = update_state.spec.value_from_t(t);
+4 -2
View File
@@ -277,8 +277,10 @@ mod painter_tests {
let action = meta.action;
let icon = config::action_meta(action)
.and_then(|meta| meta.icon)
.map(action_icon_painter)
.unwrap_or_else(|| panic!("missing icon for {action:?}"));
.map_or_else(
|| panic!("missing icon for {action:?}"),
action_icon_painter,
);
let expected = match action {
Action::EnterTextMode => top_toolbar_icon_painter(TopToolbarIcon::Text),
Action::EnterStickyNoteMode => top_toolbar_icon_painter(TopToolbarIcon::StickyNote),
@@ -391,10 +391,10 @@ pub(in crate::ui::board_picker::page_panel) fn render_page_preview(
},
);
let label = frame
.page_name()
.map(|name| trf("Page {}: {}", &[&page_number, &name]))
.unwrap_or_else(|| trf("Page {}", &[&page_number]));
let label = frame.page_name().map_or_else(
|| trf("Page {}", &[&page_number]),
|name| trf("Page {}: {}", &[&page_number, &name]),
);
let label_style = UiTextStyle {
family: "Sans",
slant: cairo::FontSlant::Normal,
+1 -1
View File
@@ -65,7 +65,7 @@ pub(super) fn render_board_palette(
);
let _ = ctx.stroke();
if active_color.map(|active| active == color).unwrap_or(false) {
if active_color.is_some_and(|active| active == color) {
constants::set_color(ctx, INPUT_CARET);
ctx.set_line_width(1.5);
draw_rounded_rect(
+8 -18
View File
@@ -296,15 +296,10 @@ pub(crate) fn render_color_picker_popup_with_engine(
// restore the inline hex actions the pre-overhaul color section carried.
let hover_pos = input_state.color_picker_popup_hover();
let size = layout.action_btn_size;
let copy_hover = hover_pos
.map(|(hx, hy)| layout.point_in_copy_button(hx, hy))
.unwrap_or(false);
let paste_hover = hover_pos
.map(|(hx, hy)| layout.point_in_paste_button(hx, hy))
.unwrap_or(false);
let eyedropper_hover = hover_pos
.map(|(hx, hy)| layout.point_in_eyedropper_button(hx, hy))
.unwrap_or(false);
let copy_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_copy_button(hx, hy));
let paste_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_paste_button(hx, hy));
let eyedropper_hover =
hover_pos.is_some_and(|(hx, hy)| layout.point_in_eyedropper_button(hx, hy));
draw_action_button(
ctx,
layout.copy_btn_x,
@@ -336,20 +331,15 @@ pub(crate) fn render_color_picker_popup_with_engine(
}
// Determine button hover states
let ok_hover = hover_pos
.map(|(hx, hy)| layout.point_in_ok_button(hx, hy))
.unwrap_or(false);
let cancel_hover = hover_pos
.map(|(hx, hy)| layout.point_in_cancel_button(hx, hy))
.unwrap_or(false);
let ok_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_ok_button(hx, hy));
let cancel_hover = hover_pos.is_some_and(|(hx, hy)| layout.point_in_cancel_button(hx, hy));
// "Default" button: only while recoloring a slot the shipped palette
// defines. It stages the built-in color instead of committing, so it is a
// secondary action next to OK/Cancel.
if let Some((default_x, default_y)) = layout.default_btn {
let default_hover = hover_pos
.map(|(hx, hy)| layout.point_in_default_button(hx, hy))
.unwrap_or(false);
let default_hover =
hover_pos.is_some_and(|(hx, hy)| layout.point_in_default_button(hx, hy));
draw_button(
engine,
ctx,
+1 -3
View File
@@ -139,9 +139,7 @@ fn query_line(
// Match count on the right, so a query that narrows to nothing says so
// before the empty list has to. Measured first: it is short and always
// wanted, so it is the query that gives way when the two would collide.
let count = match_count
.map(|count| count.to_string())
.unwrap_or_else(|| "…".to_string());
let count = match_count.map_or_else(|| "…".to_string(), |count| count.to_string());
let count_width = text_width(ctx, "Sans", CHROME_FONT_SIZE, &count);
theme::set_color(ctx, overlay::TEXT_HINT);
draw_text_right(
+5 -6
View File
@@ -332,11 +332,8 @@ impl GridPainter<'_> {
}
ctx.new_path();
let badge_metrics = measured
.badge_text_metrics
.get(badge_index)
.map(|metrics| (metrics.width, metrics.height, metrics.y_bearing))
.unwrap_or_else(|| {
let badge_metrics = measured.badge_text_metrics.get(badge_index).map_or_else(
|| {
let extents = text_extents_for_with_engine(
self.engine,
ctx,
@@ -347,7 +344,9 @@ impl GridPainter<'_> {
badge.label.as_str(),
);
(extents.width(), extents.height(), extents.y_bearing())
});
},
|metrics| (metrics.width, metrics.height, metrics.y_bearing),
);
let badge_width = badge_metrics.0 + style.badge_padding_x * 2.0;
draw_rounded_rect(
+4 -8
View File
@@ -87,13 +87,11 @@ pub(crate) fn render_help_overlay_result_with_content(
let palette_binding = bindings
.labels_for(Action::ToggleCommandPalette)
.and_then(|labels| labels.first())
.map(|label| label.as_str())
.unwrap_or(NOT_BOUND_LABEL);
.map_or(NOT_BOUND_LABEL, |label| label.as_str());
let config_binding = bindings
.labels_for(Action::OpenConfigurator)
.and_then(|labels| labels.first())
.map(|label| label.as_str())
.unwrap_or(NOT_BOUND_LABEL);
.map_or(NOT_BOUND_LABEL, |label| label.as_str());
let version_text = format!("v{}", build_info::version());
let header_hints = if quick_mode {
vec![HeaderHint {
@@ -124,13 +122,11 @@ pub(crate) fn render_help_overlay_result_with_content(
let help_binding = bindings
.labels_for(Action::ToggleHelp)
.and_then(|labels| labels.first())
.map(|label| label.as_str())
.unwrap_or("F1");
.map_or("F1", |label| label.as_str());
let quick_help_binding = bindings
.labels_for(Action::ToggleQuickHelp)
.and_then(|labels| labels.first())
.map(|label| label.as_str())
.unwrap_or("Shift+F1");
.map_or("Shift+F1", |label| label.as_str());
let note_text_base_owned;
let note_text_base: &str = if quick_mode {
note_text_base_owned = trf("{} for full help", &[&help_binding]);
+1 -3
View File
@@ -72,7 +72,5 @@ pub(super) fn toolbar_hint_label(input_state: &InputState) -> String {
}
fn tool_action_label(tool: Tool) -> &'static str {
action_for_tool(tool)
.map(action_display_label)
.unwrap_or(tr("Select"))
action_for_tool(tool).map_or(tr("Select"), action_display_label)
}
+2 -6
View File
@@ -313,9 +313,7 @@ pub(crate) fn short_label_for_event(
match event {
ToolbarEvent::ToggleFreeze if frozen_active => tr("Unfreeze"),
ToolbarEvent::ToggleZoomLock if zoom_locked => tr("Unlock Zoom"),
_ => action_for_event(event)
.map(action_short_label)
.unwrap_or(fallback),
_ => action_for_event(event).map_or(fallback, action_short_label),
}
}
@@ -328,9 +326,7 @@ pub(crate) fn tooltip_label_for_event(
match event {
ToolbarEvent::ToggleFreeze if frozen_active => tr("Unfreeze"),
ToolbarEvent::ToggleZoomLock if zoom_locked => tr("Unlock Zoom"),
_ => action_for_event(event)
.map(action_label)
.unwrap_or(fallback),
_ => action_for_event(event).map_or(fallback, action_label),
}
}
+4 -5
View File
@@ -31,11 +31,10 @@ impl ToolbarSessionModel {
.active_session_name
.clone()
.unwrap_or_else(|| tr("Default session").to_string());
let active_path_label = snapshot
.active_session_path
.as_ref()
.map(|path| path.display().to_string())
.unwrap_or_else(|| tr("No persisted session target").to_string());
let active_path_label = snapshot.active_session_path.as_ref().map_or_else(
|| tr("No persisted session target").to_string(),
|path| path.display().to_string(),
);
let target_active = snapshot.active_session_path.is_some();
let buttons: Vec<_> = vec![
ToolbarSessionButton::new(ToolbarEvent::OpenSession, tr("Open"), target_active),
@@ -34,8 +34,10 @@ fn regular_spec_owns_control_order_ids_and_events() {
let next = ids[position..]
.iter()
.position(|id| id == expected)
.map(|offset| position + offset)
.unwrap_or_else(|| panic!("{expected} missing from {ids:?}"));
.map_or_else(
|| panic!("{expected} missing from {ids:?}"),
|offset| position + offset,
);
position = next + 1;
}
+1 -2
View File
@@ -11,8 +11,7 @@ use std::path::Path;
pub fn session_display_name(path: &Path) -> String {
path.file_name()
.and_then(|name| name.to_str())
.map(str::to_string)
.unwrap_or_else(|| path.display().to_string())
.map_or_else(|| path.display().to_string(), str::to_string)
}
/// Middle-ellipsize so both the head and the distinguishing tail survive.
+2 -6
View File
@@ -35,13 +35,9 @@ impl ToolbarSnapshot {
&& state.text_editing.mode() == TextInputMode::StickyNote;
let override_tool = state.tool_override();
let thickness_targets_eraser = active_tool.uses_eraser_size()
|| override_tool
.map(|tool| tool.uses_eraser_size())
.unwrap_or(false);
|| override_tool.is_some_and(|tool| tool.uses_eraser_size());
let thickness_targets_marker = active_tool.uses_marker_opacity()
|| override_tool
.map(|tool| tool.uses_marker_opacity())
.unwrap_or(false);
|| override_tool.is_some_and(|tool| tool.uses_marker_opacity());
let eraser_kind = state.style.eraser_kind;
let eraser_mode = state.style.eraser_mode;
let thickness_value = if thickness_targets_eraser {
Loaded 100 of 104 files, more files were not shown because too many files have changed in this diff. Show more