Clippy clean

This commit is contained in:
Will Temple
2026-05-16 16:59:09 -04:00
parent ccc3984b01
commit 4347232b98
13 changed files with 134 additions and 99 deletions

View File

@@ -1,3 +1,16 @@
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["lib/*", "examples/*"] members = ["lib/*", "examples/*"]
default-members = [
"lib/reactivity",
"lib/reactivity_parsing",
"lib/ruin_app",
"lib/ruin_app_proc_macros",
"lib/runtime",
"lib/runtime_proc_macros",
"lib/ui",
"lib/ui_platform_macos",
"lib/ui_platform_wayland",
"lib/ui_renderer_wgpu",
"examples/calculator",
]

View File

@@ -177,7 +177,7 @@ mod tests {
assert_eq!(state.expression.get(), "4"); assert_eq!(state.expression.get(), "4");
assert_eq!(state.result.get(), ""); assert_eq!(state.result.get(), "");
assert_eq!(state.is_error.get(), false); assert!(!state.is_error.get());
assert_eq!(state.history.get().len(), 1); assert_eq!(state.history.get().len(), 1);
assert_eq!(state.history.get()[0].expression, "2+2"); assert_eq!(state.history.get()[0].expression, "2+2");
assert_eq!(state.history.get()[0].result, "4"); assert_eq!(state.history.get()[0].result, "4");

View File

@@ -43,10 +43,10 @@ pub struct CalcState {
impl CalcState { impl CalcState {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
expression: use_signal(|| String::new()), expression: use_signal(String::new),
result: use_signal(|| String::new()), result: use_signal(String::new),
is_error: use_signal(|| false), is_error: use_signal(|| false),
history: use_signal(|| Vec::new()), history: use_signal(Vec::new),
mode: use_signal(|| CalcMode::Basic), mode: use_signal(|| CalcMode::Basic),
fresh: use_signal(|| false), fresh: use_signal(|| false),
history_scroll: use_signal(|| 10_000.0_f32), history_scroll: use_signal(|| 10_000.0_f32),

View File

@@ -66,6 +66,13 @@ struct JsonParser {
next_id: u64, next_id: u64,
} }
struct ReuseContext<'a, 'count> {
old_text: &'a str,
new_text: &'a str,
delta: &'a EditDelta,
reused: &'count mut usize,
}
struct Cursor<'a> { struct Cursor<'a> {
text: &'a str, text: &'a str,
offset: usize, offset: usize,
@@ -114,7 +121,7 @@ async fn main() {
let parse_state = cell_in(&reactor, initial_snapshot); let parse_state = cell_in(&reactor, initial_snapshot);
let last_delta = cell_in(&reactor, None::<EditDelta>); let last_delta = cell_in(&reactor, None::<EditDelta>);
let _parser_subscription = { {
let rope = rope.clone(); let rope = rope.clone();
let parser = Rc::clone(&parser); let parser = Rc::clone(&parser);
let parse_state = parse_state.clone(); let parse_state = parse_state.clone();
@@ -283,15 +290,18 @@ impl JsonParser {
let mut root_anchor = previous.root_anchor; let mut root_anchor = previous.root_anchor;
root_anchor.map_through(delta); root_anchor.map_through(delta);
let mut reused = 0usize; let mut reused = 0usize;
let mut reuse = ReuseContext {
old_text: &previous.text,
new_text: &text,
delta,
reused: &mut reused,
};
let root = self.reuse_node( let root = self.reuse_node(
&parsed, &parsed,
Some(&previous.root), Some(&previous.root),
previous.root_anchor.byte, previous.root_anchor.byte,
root_anchor.byte, root_anchor.byte,
&previous.text, &mut reuse,
&text,
delta,
&mut reused,
); );
Ok(ParseSnapshot { Ok(ParseSnapshot {
text, text,
@@ -322,21 +332,18 @@ impl JsonParser {
old: Option<&AstNode>, old: Option<&AstNode>,
old_parent_start: usize, old_parent_start: usize,
new_parent_start: usize, new_parent_start: usize,
old_text: &str, reuse: &mut ReuseContext<'_, '_>,
new_text: &str,
delta: &EditDelta,
reused: &mut usize,
) -> AstNode { ) -> AstNode {
let parsed_local = localize(parsed.range, new_parent_start); let parsed_local = localize(parsed.range, new_parent_start);
if let Some(old) = old if let Some(old) = old
&& old.kind == parsed.kind && old.kind == parsed.kind
&& map_range(absolute_range(old, old_parent_start), delta) == parsed.range && map_range(absolute_range(old, old_parent_start), reuse.delta) == parsed.range
&& old_text.get( && reuse.old_text.get(
absolute_range(old, old_parent_start).start absolute_range(old, old_parent_start).start
..absolute_range(old, old_parent_start).end, ..absolute_range(old, old_parent_start).end,
) == new_text.get(parsed.range.start..parsed.range.end) ) == reuse.new_text.get(parsed.range.start..parsed.range.end)
{ {
*reused += count_nodes(old); *reuse.reused += count_nodes(old);
return AstNode { return AstNode {
id: old.id, id: old.id,
kind: old.kind, kind: old.kind,
@@ -359,10 +366,7 @@ impl JsonParser {
previous_child, previous_child,
next_old_parent_start, next_old_parent_start,
parsed.range.start, parsed.range.start,
old_text, reuse,
new_text,
delta,
reused,
) )
}) })
.collect(); .collect();

View File

@@ -38,6 +38,8 @@ pub struct ParseError {
pub message: String, pub message: String,
} }
pub type ParserResult<C, T, D> = Result<ParseResult<C, T, D>, ParseError>;
impl ParseError { impl ParseError {
pub fn new(message: impl Into<String>) -> Self { pub fn new(message: impl Into<String>) -> Self {
Self { Self {
@@ -66,7 +68,7 @@ pub trait IncrementalParser {
cursor: RopeCursor, cursor: RopeCursor,
fragments: &[SyntaxFragment<Self::Checkpoint, Self::Tree, Self::Diagnostic>], fragments: &[SyntaxFragment<Self::Checkpoint, Self::Tree, Self::Diagnostic>],
invalidation: ParseInvalidation<Self::Checkpoint>, invalidation: ParseInvalidation<Self::Checkpoint>,
) -> Result<ParseResult<Self::Checkpoint, Self::Tree, Self::Diagnostic>, ParseError>; ) -> ParserResult<Self::Checkpoint, Self::Tree, Self::Diagnostic>;
} }
#[cfg(test)] #[cfg(test)]

View File

@@ -1,6 +1,7 @@
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::cmp::min; use std::cmp::min;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use ruin_reactivity::{Event, Reactor, Source, event_in, source_in}; use ruin_reactivity::{Event, Reactor, Source, event_in, source_in};
@@ -139,10 +140,6 @@ impl ReactiveRope {
self.len_bytes() == 0 self.len_bytes() == 0
} }
pub fn to_string(&self) -> String {
self.slice(TextRange::new(0, self.len_bytes()))
}
pub fn point_at(&self, offset: usize) -> TextPoint { pub fn point_at(&self, offset: usize) -> TextPoint {
self.inner.structure.observe(); self.inner.structure.observe();
let offset = offset.min(self.len_bytes()); let offset = offset.min(self.len_bytes());
@@ -416,6 +413,12 @@ impl ReactiveRope {
} }
} }
impl fmt::Display for ReactiveRope {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.slice(TextRange::new(0, self.len_bytes())))
}
}
impl RopeChunk { impl RopeChunk {
pub fn text(&self) -> &str { pub fn text(&self) -> &str {
&self.text &self.text

View File

@@ -323,6 +323,13 @@ pub struct TokenTreeParser {
next_id: u64, next_id: u64,
} }
struct ReuseContext<'a, 'count> {
old_text: &'a str,
new_text: &'a str,
delta: &'a EditDelta,
reused_nodes: &'count mut usize,
}
impl TokenTreeParser { impl TokenTreeParser {
pub fn new() -> Self { pub fn new() -> Self {
Self::default() Self::default()
@@ -358,15 +365,18 @@ impl TokenTreeParser {
let mut root_anchor = previous.root_anchor; let mut root_anchor = previous.root_anchor;
root_anchor.map_through(delta); root_anchor.map_through(delta);
let mut reused_nodes = 0usize; let mut reused_nodes = 0usize;
let mut reuse = ReuseContext {
old_text: &previous.text,
new_text: &text,
delta,
reused_nodes: &mut reused_nodes,
};
let root = self.reuse_node( let root = self.reuse_node(
&raw.root, &raw.root,
Some(&previous.root), Some(&previous.root),
previous.root_anchor.byte, previous.root_anchor.byte,
root_anchor.byte, root_anchor.byte,
&previous.text, &mut reuse,
&text,
delta,
&mut reused_nodes,
); );
let total_nodes = count_nodes(&root); let total_nodes = count_nodes(&root);
@@ -403,16 +413,20 @@ impl TokenTreeParser {
old: Option<&TokenTreeNode>, old: Option<&TokenTreeNode>,
old_parent_start: usize, old_parent_start: usize,
new_parent_start: usize, new_parent_start: usize,
old_text: &str, reuse: &mut ReuseContext<'_, '_>,
new_text: &str,
delta: &EditDelta,
reused_nodes: &mut usize,
) -> TokenTreeNode { ) -> TokenTreeNode {
let parsed_local = localize(parsed.range, new_parent_start); let parsed_local = localize(parsed.range, new_parent_start);
if let Some(old) = old if let Some(old) = old.filter(|old| {
.filter(|old| can_reuse_node(old, old_parent_start, parsed, old_text, new_text, delta)) can_reuse_node(
{ old,
*reused_nodes += count_nodes(old); old_parent_start,
parsed,
reuse.old_text,
reuse.new_text,
reuse.delta,
)
}) {
*reuse.reused_nodes += count_nodes(old);
return TokenTreeNode { return TokenTreeNode {
id: old.id, id: old.id,
local_range: parsed_local, local_range: parsed_local,
@@ -432,9 +446,8 @@ impl TokenTreeParser {
.children .children
.get(index) .get(index)
.filter(|candidate| !used[index] && can_descend_into_node(candidate, child)) .filter(|candidate| !used[index] && can_descend_into_node(candidate, child))
.map(|candidate| { .inspect(|_| {
used[index] = true; used[index] = true;
candidate
}) })
.or_else(|| { .or_else(|| {
old.children.iter().enumerate().find_map( old.children.iter().enumerate().find_map(
@@ -455,10 +468,7 @@ impl TokenTreeParser {
candidate, candidate,
absolute_range(old, old_parent_start).start, absolute_range(old, old_parent_start).start,
parsed.range.start, parsed.range.start,
old_text, reuse,
new_text,
delta,
reused_nodes,
) )
}) })
.collect() .collect()
@@ -467,16 +477,7 @@ impl TokenTreeParser {
.children .children
.iter() .iter()
.map(|child| { .map(|child| {
self.reuse_node( self.reuse_node(child, None, old_parent_start, parsed.range.start, reuse)
child,
None,
old_parent_start,
parsed.range.start,
old_text,
new_text,
delta,
reused_nodes,
)
}) })
.collect() .collect()
}; };
@@ -545,13 +546,13 @@ impl<'a> Cursor<'a> {
break; break;
} }
if let Some(close) = terminator { if let Some(close) = terminator
if self.peek_char() == Some(close) { && self.peek_char() == Some(close)
{
self.bump_char(); self.bump_char();
terminated = true; terminated = true;
break; break;
} }
}
let Some(ch) = self.peek_char() else { let Some(ch) = self.peek_char() else {
break; break;
@@ -1376,7 +1377,7 @@ mod tests {
.collect() .collect()
} }
fn find_list_child<'a>(node: &'a TokenTreeNode, delimiter: DelimiterKind) -> &'a TokenTreeNode { fn find_list_child(node: &TokenTreeNode, delimiter: DelimiterKind) -> &TokenTreeNode {
node.children node.children
.iter() .iter()
.find(|child| { .find(|child| {

View File

@@ -201,7 +201,7 @@ pub(crate) fn sync_primary_selection(
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
{ {
let _ = (window, interaction_tree, selection); let _ = (window, interaction_tree, selection);
return Ok(()); Ok(())
} }
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]

View File

@@ -4,6 +4,12 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
ruin_ui = { path = "../ui" }
ruin_ui_renderer_wgpu = { path = "../ui_renderer_wgpu" }
ruin_runtime = { package = "ruin-runtime", path = "../runtime" }
tracing = "0.1"
[target.'cfg(target_os = "macos")'.dependencies]
libc = "0.2" libc = "0.2"
objc2 = "0.6.4" objc2 = "0.6.4"
objc2-core-foundation = "0.3.2" objc2-core-foundation = "0.3.2"
@@ -11,7 +17,3 @@ objc2-foundation = "0.3.2"
objc2-quartz-core = "0.3.2" objc2-quartz-core = "0.3.2"
raw-window-handle = "0.6" raw-window-handle = "0.6"
raw-window-metal = "1.1.0" raw-window-metal = "1.1.0"
ruin_ui = { path = "../ui" }
ruin_ui_renderer_wgpu = { path = "../ui_renderer_wgpu" }
ruin_runtime = { package = "ruin-runtime", path = "../runtime" }
tracing = "0.1"

View File

@@ -2,6 +2,8 @@
//! //!
//! Native backend implemented on top of Cocoa/AppKit runtime messaging. //! Native backend implemented on top of Cocoa/AppKit runtime messaging.
#![cfg(target_os = "macos")]
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::ffi::{CStr, CString, c_void}; use std::ffi::{CStr, CString, c_void};
@@ -353,9 +355,7 @@ impl ResizePipeline {
} }
fn note_presented_scene(&mut self, scene_viewport: UiSize) -> Option<WindowConfigured> { fn note_presented_scene(&mut self, scene_viewport: UiSize) -> Option<WindowConfigured> {
let Some(presented_configuration) = self.active_resize else { let presented_configuration = self.active_resize?;
return None;
};
if presented_configuration.actual_inner_size != scene_viewport { if presented_configuration.actual_inner_size != scene_viewport {
return None; return None;
} }
@@ -365,9 +365,7 @@ impl ResizePipeline {
self.next_resize = None; self.next_resize = None;
} }
let Some(next_resize) = self.next_resize.take() else { let next_resize = self.next_resize.take()?;
return None;
};
self.active_resize = Some(next_resize); self.active_resize = Some(next_resize);
Some(next_resize) Some(next_resize)
} }

View File

@@ -4,12 +4,14 @@ version = "0.1.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
libc = "0.2"
raw-window-handle = "0.6"
ruin_runtime = { package = "ruin-runtime", path = "../runtime" } ruin_runtime = { package = "ruin-runtime", path = "../runtime" }
ruin_ui = { path = "../ui" } ruin_ui = { path = "../ui" }
ruin_ui_renderer_wgpu = { path = "../ui_renderer_wgpu" } ruin_ui_renderer_wgpu = { path = "../ui_renderer_wgpu" }
tracing = "0.1" tracing = "0.1"
[target.'cfg(target_os = "linux")'.dependencies]
libc = "0.2"
raw-window-handle = "0.6"
wayland-backend = { version = "0.3", features = ["client_system"] } wayland-backend = { version = "0.3", features = ["client_system"] }
wayland-client = "0.31" wayland-client = "0.31"
wayland-protocols = { version = "0.32", features = ["client", "staging", "unstable"] } wayland-protocols = { version = "0.32", features = ["client", "staging", "unstable"] }

View File

@@ -1,3 +1,5 @@
#![cfg(target_os = "linux")]
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::error::Error; use std::error::Error;

View File

@@ -1163,10 +1163,12 @@ fn fs_main(input: VertexOut) -> @location(0) vec4<f32> {
glyph_rect, glyph_rect,
atlas_glyph.atlas_rect, atlas_glyph.atlas_rect,
clip_rect, clip_rect,
GlyphVertexContext {
logical_size, logical_size,
self.scale_factor, scale_factor: self.scale_factor,
resolved_color, color: resolved_color,
active_clip, clip: active_clip,
},
); );
} }
} }
@@ -1888,34 +1890,40 @@ fn build_textured_vertices(
]) ])
} }
#[allow(dead_code)]
#[derive(Clone, Copy)]
struct GlyphVertexContext {
logical_size: UiSize,
scale_factor: f32,
color: Color,
clip: ActiveClip,
}
#[allow(dead_code)] #[allow(dead_code)]
fn push_glyph_vertices( fn push_glyph_vertices(
vertices: &mut Vec<TextVertex>, vertices: &mut Vec<TextVertex>,
glyph_rect: PixelRect, glyph_rect: PixelRect,
atlas_rect: AtlasRect, atlas_rect: AtlasRect,
clip_rect: Option<PixelRect>, clip_rect: Option<PixelRect>,
logical_size: UiSize, context: GlyphVertexContext,
scale_factor: f32,
color: Color,
clip: ActiveClip,
) { ) {
let Some((dest_rect, uv_rect)) = clipped_glyph_quad(glyph_rect, atlas_rect, clip_rect) else { let Some((dest_rect, uv_rect)) = clipped_glyph_quad(glyph_rect, atlas_rect, clip_rect) else {
return; return;
}; };
let scale_factor = scale_factor.max(1.0); let scale_factor = context.scale_factor.max(1.0);
let logical_left = dest_rect.left as f32 / scale_factor; let logical_left = dest_rect.left as f32 / scale_factor;
let logical_top = dest_rect.top as f32 / scale_factor; let logical_top = dest_rect.top as f32 / scale_factor;
let logical_right = dest_rect.right as f32 / scale_factor; let logical_right = dest_rect.right as f32 / scale_factor;
let logical_bottom = dest_rect.bottom as f32 / scale_factor; let logical_bottom = dest_rect.bottom as f32 / scale_factor;
let left = to_ndc_x(logical_left, logical_size.width.max(1.0)); let left = to_ndc_x(logical_left, context.logical_size.width.max(1.0));
let right = to_ndc_x(logical_right, logical_size.width.max(1.0)); let right = to_ndc_x(logical_right, context.logical_size.width.max(1.0));
let top = to_ndc_y(logical_top, logical_size.height.max(1.0)); let top = to_ndc_y(logical_top, context.logical_size.height.max(1.0));
let bottom = to_ndc_y(logical_bottom, logical_size.height.max(1.0)); let bottom = to_ndc_y(logical_bottom, context.logical_size.height.max(1.0));
let color = color_to_f32(color); let color = color_to_f32(context.color);
let clip_rect = clip_rect_array(clip); let clip_rect = clip_rect_array(context.clip);
let (rounded_clip_rect, clip_params) = rounded_clip_arrays(clip); let (rounded_clip_rect, clip_params) = rounded_clip_arrays(context.clip);
vertices.extend_from_slice(&[ vertices.extend_from_slice(&[
TextVertex { TextVertex {
position: [left, top], position: [left, top],
@@ -2335,9 +2343,7 @@ fn text_raster_clip(
let text_bounds = Rect::new(text.origin.x, text.origin.y, bounds.width, bounds.height); let text_bounds = Rect::new(text.origin.x, text.origin.y, bounds.width, bounds.height);
absolute_clip = intersect_rects(absolute_clip, Some(text_bounds)); absolute_clip = intersect_rects(absolute_clip, Some(text_bounds));
} }
if absolute_clip.is_none() { absolute_clip?;
return None;
}
Some(absolute_clip.map(|rect| { Some(absolute_clip.map(|rect| {
Rect::new( Rect::new(
@@ -2524,8 +2530,8 @@ fn scale_glyph_cache_key(cache_key: CacheKey, scale_factor: f32) -> CacheKey {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{
ActiveClip, AtlasRect, PixelRect, blend_rgba, build_text_vertices, build_vertices, ActiveClip, AtlasRect, GlyphVertexContext, PixelRect, blend_rgba, build_text_vertices,
clip_rect_array, push_clip_state, push_glyph_vertices, rounded_clip_arrays, build_vertices, clip_rect_array, push_clip_state, push_glyph_vertices, rounded_clip_arrays,
scale_glyph_cache_key, text_texture_key, scale_glyph_cache_key, text_texture_key,
}; };
use cosmic_text::{CacheKey, CacheKeyFlags, SubpixelBin, fontdb}; use cosmic_text::{CacheKey, CacheKeyFlags, SubpixelBin, fontdb};
@@ -2648,10 +2654,12 @@ mod tests {
height: 20, height: 20,
}, },
None, None,
UiSize::new(100.0, 100.0), GlyphVertexContext {
2.0, logical_size: UiSize::new(100.0, 100.0),
Color::rgb(0xFF, 0xFF, 0xFF), scale_factor: 2.0,
ActiveClip::default(), color: Color::rgb(0xFF, 0xFF, 0xFF),
clip: ActiveClip::default(),
},
); );
assert_eq!(vertices.len(), 6); assert_eq!(vertices.len(), 6);