Fixed **many** clippy lints, and one bug.

This commit is contained in:
Mark Tomlin 2023-12-25 13:06:02 -05:00 committed by Jeremy Soller
parent d289670def
commit aecb80eaed
6 changed files with 155 additions and 201 deletions

View file

@ -364,7 +364,7 @@ impl App {
let position = self.nav_model.position(id).unwrap_or(0); let position = self.nav_model.position(id).unwrap_or(0);
self.open_folder(&path, position + 1, 1); self.open_folder(path, position + 1, 1);
} }
pub fn open_tab(&mut self, path_opt: Option<PathBuf>) -> Option<segmented_button::Entity> { pub fn open_tab(&mut self, path_opt: Option<PathBuf>) -> Option<segmented_button::Entity> {
@ -381,14 +381,11 @@ impl App {
//TODO: allow files to be open multiple times //TODO: allow files to be open multiple times
let mut activate_opt = None; let mut activate_opt = None;
for entity in self.tab_model.iter() { for entity in self.tab_model.iter() {
match self.tab_model.data::<Tab>(entity) { if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
Some(Tab::Editor(tab)) => { if tab.path_opt.as_ref() == Some(&canonical) {
if tab.path_opt.as_ref() == Some(&canonical) { activate_opt = Some(entity);
activate_opt = Some(entity); break;
break;
}
} }
_ => {}
} }
} }
if let Some(entity) = activate_opt { if let Some(entity) = activate_opt {
@ -428,15 +425,18 @@ impl App {
} }
fn save_config(&mut self) -> Command<Message> { fn save_config(&mut self) -> Command<Message> {
match self.config_handler { if let Some(ref config_handler) = self.config_handler {
Some(ref config_handler) => match self.config.write_entry(&config_handler) { if let Err(err) = self.config.write_entry(config_handler) {
Ok(()) => {} log::error!("failed to save config: {}", err);
Err(err) => { }
log::error!("failed to save config: {}", err);
}
},
None => {}
} }
if let Some(ref config_handler) = self.config_handler {
if let Err(err) = self.config.write_entry(config_handler) {
log::error!("failed to save config: {}", err);
}
}
self.update_config() self.update_config()
} }
@ -449,43 +449,40 @@ impl App {
// Locate tree node to activate // Locate tree node to activate
let mut active_id = segmented_button::Entity::default(); let mut active_id = segmented_button::Entity::default();
match tab_path_opt {
Some(tab_path) => { if let Some(tab_path) = tab_path_opt {
// Automatically expand tree to find and select active file // Automatically expand tree to find and select active file
loop { loop {
let mut expand_opt = None; let mut expand_opt = None;
for id in self.nav_model.iter() { for id in self.nav_model.iter() {
match self.nav_model.data(id) { if let Some(node) = self.nav_model.data(id) {
Some(node) => match node { match node {
ProjectNode::Folder { path, open, .. } => { ProjectNode::Folder { path, open, .. } => {
if tab_path.starts_with(path) && !*open { if tab_path.starts_with(path) && !*open {
expand_opt = Some(id); expand_opt = Some(id);
break; break;
}
} }
ProjectNode::File { path, .. } => { }
if path == &tab_path { ProjectNode::File { path, .. } => {
active_id = id; if path == &tab_path {
break; active_id = id;
} break;
} }
}, }
None => {}
}
}
match expand_opt {
Some(id) => {
//TODO: can this be optimized?
// Command not used becuase opening a folder just returns Command::none
let _ = self.on_nav_select(id);
}
None => {
break;
} }
} }
} }
match expand_opt {
Some(id) => {
//TODO: can this be optimized?
// Command not used becuase opening a folder just returns Command::none
let _ = self.on_nav_select(id);
}
None => {
break;
}
}
} }
None => {}
} }
self.nav_model.activate(active_id); self.nav_model.activate(active_id);
} }
@ -502,7 +499,7 @@ impl App {
} }
tab.title() tab.title()
} }
None => format!("No Open File"), None => "No Open File".to_string(),
}; };
let window_title = format!("{title} - COSMIC Text Editor"); let window_title = format!("{title} - COSMIC Text Editor");
@ -515,23 +512,21 @@ impl App {
let mut character_count = 0; let mut character_count = 0;
let mut character_count_no_spaces = 0; let mut character_count_no_spaces = 0;
let mut line_count = 0; let mut line_count = 0;
match self.active_tab() {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.active_tab() {
let editor = tab.editor.lock().unwrap(); let editor = tab.editor.lock().unwrap();
editor.with_buffer(|buffer| { editor.with_buffer(|buffer| {
line_count = buffer.lines.len(); line_count = buffer.lines.len();
for line in buffer.lines.iter() { for line in buffer.lines.iter() {
//TODO: do graphemes? //TODO: do graphemes?
for c in line.text().chars() { for c in line.text().chars() {
character_count += 1; character_count += 1;
if !c.is_whitespace() { if !c.is_whitespace() {
character_count_no_spaces += 1; character_count_no_spaces += 1;
}
} }
} }
}); }
} });
_ => {}
} }
widget::settings::view_column(vec![widget::settings::view_section("") widget::settings::view_column(vec![widget::settings::view_section("")
@ -598,7 +593,7 @@ impl App {
project_path, project_path,
err err
); );
&old_path old_path
} }
}; };
format!( format!(
@ -752,7 +747,7 @@ impl App {
)) ))
.font(Font::MONOSPACE) .font(Font::MONOSPACE)
.into(), .into(),
widget::text(format!("{}", line_search_result.text)) widget::text(line_search_result.text.to_string())
.font(Font::MONOSPACE) .font(Font::MONOSPACE)
.into(), .into(),
]) ])
@ -848,7 +843,7 @@ impl App {
widget::settings::item::builder(fl!("default-font")).control(widget::dropdown( widget::settings::item::builder(fl!("default-font")).control(widget::dropdown(
&self.font_names, &self.font_names,
font_selected, font_selected,
|index| Message::DefaultFont(index), Message::DefaultFont,
)), )),
) )
.add( .add(
@ -914,7 +909,7 @@ impl Application for App {
//TODO: get localized name if possible //TODO: get localized name if possible
let font_name = face let font_name = face
.families .families
.get(0) .first()
.map_or_else(|| face.post_script_name.to_string(), |x| x.0.to_string()); .map_or_else(|| face.post_script_name.to_string(), |x| x.0.to_string());
font_names.push(font_name); font_names.push(font_name);
} }
@ -1030,11 +1025,8 @@ impl Application for App {
// Toggle open state and get clone of node data // Toggle open state and get clone of node data
let node_opt = match self.nav_model.data_mut::<ProjectNode>(id) { let node_opt = match self.nav_model.data_mut::<ProjectNode>(id) {
Some(node) => { Some(node) => {
match node { if let ProjectNode::Folder { open, .. } = node {
ProjectNode::Folder { open, .. } => { *open = !*open;
*open = !*open;
}
_ => {}
} }
Some(node.clone()) Some(node.clone())
} }
@ -1055,12 +1047,7 @@ impl Application for App {
self.open_folder(path, position + 1, indent + 1); self.open_folder(path, position + 1, indent + 1);
} else { } else {
// Close folder // Close folder
loop { while let Some(child_id) = self.nav_model.entity_at(position + 1) {
let child_id = match self.nav_model.entity_at(position + 1) {
Some(some) => some,
None => break,
};
if self.nav_model.indent(child_id).unwrap_or(0) > indent { if self.nav_model.indent(child_id).unwrap_or(0) > indent {
self.nav_model.remove(child_id); self.nav_model.remove(child_id);
} else { } else {
@ -1103,18 +1090,17 @@ impl Application for App {
Message::CloseProject => { Message::CloseProject => {
log::info!("TODO"); log::info!("TODO");
} }
Message::Copy => match self.active_tab() { Message::Copy => {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.active_tab() {
let editor = tab.editor.lock().unwrap(); let editor = tab.editor.lock().unwrap();
let selection_opt = editor.copy_selection(); let selection_opt = editor.copy_selection();
if let Some(selection) = selection_opt { if let Some(selection) = selection_opt {
return clipboard::write(selection); return clipboard::write(selection);
} }
} }
_ => {} }
}, Message::Cut => {
Message::Cut => match self.active_tab() { if let Some(Tab::Editor(tab)) = self.active_tab() {
Some(Tab::Editor(tab)) => {
let mut editor = tab.editor.lock().unwrap(); let mut editor = tab.editor.lock().unwrap();
let selection_opt = editor.copy_selection(); let selection_opt = editor.copy_selection();
editor.start_change(); editor.start_change();
@ -1124,8 +1110,7 @@ impl Application for App {
return clipboard::write(selection); return clipboard::write(selection);
} }
} }
_ => {} }
},
Message::DefaultFont(index) => { Message::DefaultFont(index) => {
match self.font_names.get(index) { match self.font_names.get(index) {
Some(font_name) => { Some(font_name) => {
@ -1206,22 +1191,19 @@ impl Application for App {
Message::NotifyEvent(event) => { Message::NotifyEvent(event) => {
let mut needs_reload = Vec::new(); let mut needs_reload = Vec::new();
for entity in self.tab_model.iter() { for entity in self.tab_model.iter() {
match self.tab_model.data::<Tab>(entity) { if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
Some(Tab::Editor(tab)) => { if let Some(path) = &tab.path_opt {
if let Some(path) = &tab.path_opt { if event.paths.contains(path) {
if event.paths.contains(&path) { if tab.changed() {
if tab.changed() { log::warn!(
log::warn!( "file changed externally before being saved: {:?}",
"file changed externally before being saved: {:?}", path
path );
); } else {
} else { needs_reload.push(entity);
needs_reload.push(entity);
}
} }
} }
} }
_ => {}
} }
} }
@ -1242,11 +1224,8 @@ impl Application for App {
self.watcher_opt = Some(watcher); self.watcher_opt = Some(watcher);
for entity in self.tab_model.iter() { for entity in self.tab_model.iter() {
match self.tab_model.data::<Tab>(entity) { if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
Some(Tab::Editor(tab)) => { tab.watch(&mut self.watcher_opt);
tab.watch(&mut self.watcher_opt);
}
_ => {}
} }
} }
} }
@ -1363,15 +1342,14 @@ impl Application for App {
None => message::none(), None => message::none(),
}); });
} }
Message::PasteValue(value) => match self.active_tab() { Message::PasteValue(value) => {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.active_tab() {
let mut editor = tab.editor.lock().unwrap(); let mut editor = tab.editor.lock().unwrap();
editor.start_change(); editor.start_change();
editor.insert_string(&value, None); editor.insert_string(&value, None);
editor.finish_change(); editor.finish_change();
} }
_ => {} }
},
Message::PrepareGitDiff(project_path, path, staged) => { Message::PrepareGitDiff(project_path, path, staged) => {
return Command::perform( return Command::perform(
async move { async move {
@ -1446,27 +1424,23 @@ impl Application for App {
//TODO: prompt for save? //TODO: prompt for save?
return window::close(window::Id::MAIN); return window::close(window::Id::MAIN);
} }
Message::Redo => match self.active_tab() { Message::Redo => {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.active_tab() {
let mut editor = tab.editor.lock().unwrap(); let mut editor = tab.editor.lock().unwrap();
editor.redo(); editor.redo();
} }
_ => {} }
},
Message::Save => { Message::Save => {
let mut title_opt = None; let mut title_opt = None;
match self.active_tab_mut() { if let Some(Tab::Editor(tab)) = self.active_tab_mut() {
Some(Tab::Editor(tab)) => { #[cfg(feature = "rfd")]
#[cfg(feature = "rfd")] if tab.path_opt.is_none() {
if tab.path_opt.is_none() { //TODO: use async file dialog
//TODO: use async file dialog tab.path_opt = rfd::FileDialog::new().save_file();
tab.path_opt = rfd::FileDialog::new().save_file();
}
title_opt = Some(tab.title());
tab.save();
} }
_ => {} title_opt = Some(tab.title());
tab.save();
} }
if let Some(title) = title_opt { if let Some(title) = title_opt {
@ -1474,22 +1448,19 @@ impl Application for App {
} }
} }
Message::SelectAll => { Message::SelectAll => {
match self.active_tab_mut() { if let Some(Tab::Editor(tab)) = self.active_tab_mut() {
Some(Tab::Editor(tab)) => { let mut editor = tab.editor.lock().unwrap();
let mut editor = tab.editor.lock().unwrap();
// Set cursor to lowest possible value // Set cursor to lowest possible value
editor.set_cursor(Cursor::new(0, 0)); editor.set_cursor(Cursor::new(0, 0));
// Set selection end to highest possible value // Set selection end to highest possible value
let selection = editor.with_buffer(|buffer| { let selection = editor.with_buffer(|buffer| {
let last_line = buffer.lines.len().saturating_sub(1); let last_line = buffer.lines.len().saturating_sub(1);
let last_index = buffer.lines[last_line].text().len(); let last_index = buffer.lines[last_line].text().len();
Selection::Normal(Cursor::new(last_line, last_index)) Selection::Normal(Cursor::new(last_line, last_index))
}); });
editor.set_selection(selection); editor.set_selection(selection);
}
_ => {}
} }
} }
Message::SystemThemeModeChange(_theme_mode) => { Message::SystemThemeModeChange(_theme_mode) => {
@ -1512,15 +1483,14 @@ impl Application for App {
self.tab_model.activate(entity); self.tab_model.activate(entity);
return self.update_tab(); return self.update_tab();
} }
Message::TabChanged(entity) => match self.tab_model.data::<Tab>(entity) { Message::TabChanged(entity) => {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
let mut title = tab.title(); let mut title = tab.title();
//TODO: better way of adding change indicator //TODO: better way of adding change indicator
title.push_str(" \u{2022}"); title.push_str(" \u{2022}");
self.tab_model.text_set(entity, title); self.tab_model.text_set(entity, title);
} }
_ => {} }
},
Message::TabClose(entity) => { Message::TabClose(entity) => {
// Activate closest item // Activate closest item
if let Some(position) = self.tab_model.position(entity) { if let Some(position) = self.tab_model.position(entity) {
@ -1542,32 +1512,25 @@ impl Application for App {
return self.update_tab(); return self.update_tab();
} }
Message::TabContextAction(entity, action) => { Message::TabContextAction(entity, action) => {
match self.tab_model.data_mut::<Tab>(entity) { if let Some(Tab::Editor(tab)) = self.tab_model.data_mut::<Tab>(entity) {
Some(Tab::Editor(tab)) => { // Close context menu
// Close context menu tab.context_menu = None;
tab.context_menu = None; // Run action's message
// Run action's message return self.update(action.message());
return self.update(action.message());
}
_ => {}
} }
} }
Message::TabContextMenu(entity, position_opt) => { Message::TabContextMenu(entity, position_opt) => {
match self.tab_model.data_mut::<Tab>(entity) { if let Some(Tab::Editor(tab)) = self.tab_model.data_mut::<Tab>(entity) {
Some(Tab::Editor(tab)) => { // Update context menu
// Update context menu tab.context_menu = position_opt;
tab.context_menu = position_opt;
}
_ => {}
} }
} }
Message::TabSetCursor(entity, cursor) => match self.tab_model.data::<Tab>(entity) { Message::TabSetCursor(entity, cursor) => {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
let mut editor = tab.editor.lock().unwrap(); let mut editor = tab.editor.lock().unwrap();
editor.set_cursor(cursor); editor.set_cursor(cursor);
} }
_ => {} }
},
Message::TabWidth(tab_width) => { Message::TabWidth(tab_width) => {
self.config.tab_width = tab_width; self.config.tab_width = tab_width;
return self.save_config(); return self.save_config();
@ -1599,7 +1562,7 @@ impl Application for App {
let mut project_status = Vec::new(); let mut project_status = Vec::new();
for (project_name, project_path) in projects.iter() { for (project_name, project_path) in projects.iter() {
//TODO: send errors to UI //TODO: send errors to UI
match GitRepository::new(&project_path) { match GitRepository::new(project_path) {
Ok(repo) => match repo.status().await { Ok(repo) => match repo.status().await {
Ok(status) => { Ok(status) => {
if !status.is_empty() { if !status.is_empty() {
@ -1658,13 +1621,12 @@ impl Application for App {
self.config.word_wrap = !self.config.word_wrap; self.config.word_wrap = !self.config.word_wrap;
return self.save_config(); return self.save_config();
} }
Message::Undo => match self.active_tab() { Message::Undo => {
Some(Tab::Editor(tab)) => { if let Some(Tab::Editor(tab)) = self.active_tab() {
let mut editor = tab.editor.lock().unwrap(); let mut editor = tab.editor.lock().unwrap();
editor.undo(); editor.undo();
} }
_ => {} }
},
Message::VimBindings(vim_bindings) => { Message::VimBindings(vim_bindings) => {
self.config.vim_bindings = vim_bindings; self.config.vim_bindings = vim_bindings;
return self.save_config(); return self.save_config();
@ -1727,15 +1689,11 @@ impl Application for App {
ViMode::Normal => { ViMode::Normal => {
format!("{}", parser.cmd) format!("{}", parser.cmd)
} }
ViMode::Insert => { ViMode::Insert => "-- INSERT --".to_string(),
format!("-- INSERT --")
}
ViMode::Extra(extra) => { ViMode::Extra(extra) => {
format!("{}{}", parser.cmd, extra) format!("{}{}", parser.cmd, extra)
} }
ViMode::Replace => { ViMode::Replace => "-- REPLACE --".to_string(),
format!("-- REPLACE --")
}
ViMode::Visual => { ViMode::Visual => {
format!("-- VISUAL -- {}", parser.cmd) format!("-- VISUAL -- {}", parser.cmd)
} }

View file

@ -33,20 +33,20 @@ macro_rules! menu_button {
} }
pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> Element<'a, Message> { pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> Element<'a, Message> {
let menu_item = |label, action| { let menu_item = |menu_label, menu_action| {
let mut key = String::new(); let mut key = String::new();
for (key_bind, action) in config.keybinds.iter() { for (key_bind, key_action) in config.keybinds.iter() {
if action == action { if key_action == &menu_action {
key = key_bind.to_string(); key = key_bind.to_string();
break; break;
} }
} }
menu_button!( menu_button!(
widget::text(label), widget::text(menu_label),
horizontal_space(Length::Fill), horizontal_space(Length::Fill),
widget::text(key) widget::text(key)
) )
.on_press(Message::TabContextAction(entity, action)) .on_press(Message::TabContextAction(entity, menu_action))
}; };
widget::container(column!( widget::container(column!(

View file

@ -76,15 +76,17 @@ impl Ord for ProjectNode {
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
match self { match self {
// Folders are always before files // Folders are always before files
Self::Folder { .. } => match other { Self::Folder { .. } => {
Self::File { .. } => return Ordering::Less, if let Self::File { .. } = other {
_ => {} return Ordering::Less;
}, }
}
// Files are always after folders // Files are always after folders
Self::File { .. } => match other { Self::File { .. } => {
Self::Folder { .. } => return Ordering::Greater, if let Self::Folder { .. } = other {
_ => {} return Ordering::Greater;
}, }
}
} }
self.name().cmp(other.name()) self.name().cmp(other.name())
} }

View file

@ -54,13 +54,10 @@ impl ProjectSearchResult {
} }
}; };
match entry.file_type() { if let Some(file_type) = entry.file_type() {
Some(file_type) => { if file_type.is_dir() {
if file_type.is_dir() { continue;
continue;
}
} }
None => {}
} }
let entry_path = entry.path(); let entry_path = entry.path();
@ -68,7 +65,7 @@ impl ProjectSearchResult {
let mut lines = Vec::new(); let mut lines = Vec::new();
match searcher.search_path( match searcher.search_path(
&matcher, &matcher,
&entry_path, entry_path,
UTF8(|number_u64, text| { UTF8(|number_u64, text| {
match usize::try_from(number_u64) { match usize::try_from(number_u64) {
Ok(number) => match matcher.find(text.as_bytes()) { Ok(number) => match matcher.find(text.as_bytes()) {

View file

@ -161,7 +161,7 @@ impl EditorTab {
pub fn watch(&self, watcher_opt: &mut Option<notify::RecommendedWatcher>) { pub fn watch(&self, watcher_opt: &mut Option<notify::RecommendedWatcher>) {
if let Some(path) = &self.path_opt { if let Some(path) = &self.path_opt {
if let Some(watcher) = watcher_opt { if let Some(watcher) = watcher_opt {
match watcher.watch(&path, notify::RecursiveMode::NonRecursive) { match watcher.watch(path, notify::RecursiveMode::NonRecursive) {
Ok(()) => { Ok(()) => {
log::info!("watching {:?} for changes", path); log::info!("watching {:?} for changes", path);
} }

View file

@ -119,7 +119,6 @@ fn draw_rect(
let alpha = (color >> 24) & 0xFF; let alpha = (color >> 24) & 0xFF;
if alpha == 0 { if alpha == 0 {
// Do not draw if alpha is zero // Do not draw if alpha is zero
return;
} else if alpha >= 255 { } else if alpha >= 255 {
// Handle overwrite // Handle overwrite
for y in start_y..start_y + h { for y in start_y..start_y + h {
@ -172,7 +171,7 @@ fn draw_rect(
} }
} }
impl<'a, 'editor, Message, Renderer> Widget<Message, Renderer> for TextBox<'a, Message> impl<'a, Message, Renderer> Widget<Message, Renderer> for TextBox<'a, Message>
where where
Message: Clone, Message: Clone,
Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>, Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>,
@ -233,9 +232,8 @@ where
) -> mouse::Interaction { ) -> mouse::Interaction {
let state = tree.state.downcast_ref::<State>(); let state = tree.state.downcast_ref::<State>();
match &state.dragging { if let Some(Dragging::Scrollbar { .. }) = &state.dragging {
Some(Dragging::Scrollbar { .. }) => return mouse::Interaction::Idle, return mouse::Interaction::Idle;
_ => {}
} }
if let Some(p) = cursor_position.position_in(layout.bounds()) { if let Some(p) = cursor_position.position_in(layout.bounds()) {
@ -507,10 +505,9 @@ where
)); ));
} }
let image_position = let image_position = layout.position() + [self.padding.left, self.padding.top].into();
layout.position() + [self.padding.left as f32, self.padding.top as f32].into();
if let Some(ref handle) = *handle_opt { if let Some(ref handle) = *handle_opt {
let image_size = image::Renderer::dimensions(renderer, &handle); let image_size = image::Renderer::dimensions(renderer, handle);
image::Renderer::draw( image::Renderer::draw(
renderer, renderer,
handle.clone(), handle.clone(),
@ -761,7 +758,7 @@ where
Event::Mouse(MouseEvent::WheelScrolled { delta }) => { Event::Mouse(MouseEvent::WheelScrolled { delta }) => {
if let Some(_p) = cursor_position.position_in(layout.bounds()) { if let Some(_p) = cursor_position.position_in(layout.bounds()) {
match delta { match delta {
ScrollDelta::Lines { x, y } => { ScrollDelta::Lines { x: _, y } => {
//TODO: this adjustment is just a guess! //TODO: this adjustment is just a guess!
state.scroll_pixels = 0.0; state.scroll_pixels = 0.0;
let lines = (-y * 6.0) as i32; let lines = (-y * 6.0) as i32;
@ -770,7 +767,7 @@ where
} }
status = Status::Captured; status = Status::Captured;
} }
ScrollDelta::Pixels { x, y } => { ScrollDelta::Pixels { x: _, y } => {
//TODO: this adjustment is just a guess! //TODO: this adjustment is just a guess!
state.scroll_pixels -= y * 6.0; state.scroll_pixels -= y * 6.0;
let mut lines = 0; let mut lines = 0;
@ -804,7 +801,7 @@ where
} }
} }
impl<'a, 'editor, Message, Renderer> From<TextBox<'a, Message>> for Element<'a, Message, Renderer> impl<'a, Message, Renderer> From<TextBox<'a, Message>> for Element<'a, Message, Renderer>
where where
Message: Clone + 'a, Message: Clone + 'a,
Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>, Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>,