Make `Application` and `Sandbox` return a `Result`

This commit is contained in:
Héctor Ramón Jiménez 2020-09-08 00:35:17 +02:00
parent faa12382d4
commit c1f79b40cf
40 changed files with 166 additions and 58 deletions

View File

@ -78,6 +78,7 @@ members = [
[dependencies] [dependencies]
iced_core = { version = "0.2", path = "core" } iced_core = { version = "0.2", path = "core" }
iced_futures = { version = "0.1", path = "futures" } iced_futures = { version = "0.1", path = "futures" }
thiserror = "1.0"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
iced_winit = { version = "0.1", path = "winit" } iced_winit = { version = "0.1", path = "winit" }

View File

@ -3,11 +3,11 @@ use iced::{
button, Align, Button, Column, Element, Length, Sandbox, Settings, Text, button, Align, Button, Column, Element, Length, Sandbox, Settings, Text,
}; };
pub fn main() { pub fn main() -> iced::Result {
Example::run(Settings { Example::run(Settings {
antialiasing: true, antialiasing: true,
..Settings::default() ..Settings::default()
}); })
} }
#[derive(Default)] #[derive(Default)]

View File

@ -4,7 +4,7 @@ use iced::{
Point, Rectangle, Settings, Subscription, Vector, Point, Rectangle, Settings, Subscription, Vector,
}; };
pub fn main() { pub fn main() -> iced::Result {
Clock::run(Settings { Clock::run(Settings {
antialiasing: true, antialiasing: true,
..Settings::default() ..Settings::default()

View File

@ -8,7 +8,7 @@ use palette::{self, Hsl, Limited, Srgb};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
pub fn main() { pub fn main() -> iced::Result {
ColorPalette::run(Settings { ColorPalette::run(Settings {
antialiasing: true, antialiasing: true,
..Settings::default() ..Settings::default()

View File

@ -1,6 +1,6 @@
use iced::{button, Align, Button, Column, Element, Sandbox, Settings, Text}; use iced::{button, Align, Button, Column, Element, Sandbox, Settings, Text};
pub fn main() { pub fn main() -> iced::Result {
Counter::run(Settings::default()) Counter::run(Settings::default())
} }

View File

@ -90,7 +90,7 @@ use iced::{
Slider, Text, Slider, Text,
}; };
pub fn main() { pub fn main() -> iced::Result {
Example::run(Settings::default()) Example::run(Settings::default())
} }

View File

@ -5,7 +5,7 @@ use iced::{
mod download; mod download;
pub fn main() { pub fn main() -> iced::Result {
Example::run(Settings::default()) Example::run(Settings::default())
} }

View File

@ -3,7 +3,7 @@ use iced::{
Element, Length, Settings, Subscription, Text, Element, Length, Settings, Subscription, Text,
}; };
pub fn main() { pub fn main() -> iced::Result {
Events::run(Settings::default()) Events::run(Settings::default())
} }

View File

@ -16,7 +16,7 @@ use iced::{
use preset::Preset; use preset::Preset;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
pub fn main() { pub fn main() -> iced::Result {
GameOfLife::run(Settings { GameOfLife::run(Settings {
antialiasing: true, antialiasing: true,
..Settings::default() ..Settings::default()

View File

@ -165,7 +165,7 @@ use iced::{
}; };
use rainbow::Rainbow; use rainbow::Rainbow;
pub fn main() { pub fn main() -> iced::Result {
Example::run(Settings::default()) Example::run(Settings::default())
} }

View File

@ -4,7 +4,7 @@ use iced::{
Settings, Text, Settings, Text,
}; };
pub fn main() { pub fn main() -> iced::Result {
Example::run(Settings::default()) Example::run(Settings::default())
} }

View File

@ -3,7 +3,7 @@ use iced::{
Sandbox, Scrollable, Settings, Space, Text, Sandbox, Scrollable, Settings, Space, Text,
}; };
pub fn main() { pub fn main() -> iced::Result {
Example::run(Settings::default()) Example::run(Settings::default())
} }

View File

@ -3,7 +3,7 @@ use iced::{
Container, Element, Image, Length, Row, Settings, Text, Container, Element, Image, Length, Row, Settings, Text,
}; };
pub fn main() { pub fn main() -> iced::Result {
Pokedex::run(Settings::default()) Pokedex::run(Settings::default())
} }

View File

@ -1,6 +1,6 @@
use iced::{slider, Column, Element, ProgressBar, Sandbox, Settings, Slider}; use iced::{slider, Column, Element, ProgressBar, Sandbox, Settings, Slider};
pub fn main() { pub fn main() -> iced::Result {
Progress::run(Settings::default()) Progress::run(Settings::default())
} }

View File

@ -14,7 +14,7 @@ use iced::{
use std::time::Instant; use std::time::Instant;
pub fn main() { pub fn main() -> iced::Result {
SolarSystem::run(Settings { SolarSystem::run(Settings {
antialiasing: true, antialiasing: true,
..Settings::default() ..Settings::default()

View File

@ -5,7 +5,7 @@ use iced::{
}; };
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
pub fn main() { pub fn main() -> iced::Result {
Stopwatch::run(Settings::default()) Stopwatch::run(Settings::default())
} }

View File

@ -4,7 +4,7 @@ use iced::{
Scrollable, Settings, Slider, Space, Text, TextInput, Scrollable, Settings, Slider, Space, Text, TextInput,
}; };
pub fn main() { pub fn main() -> iced::Result {
Styling::run(Settings::default()) Styling::run(Settings::default())
} }

View File

@ -1,6 +1,6 @@
use iced::{Container, Element, Length, Sandbox, Settings, Svg}; use iced::{Container, Element, Length, Sandbox, Settings, Svg};
pub fn main() { pub fn main() -> iced::Result {
Tiger::run(Settings::default()) Tiger::run(Settings::default())
} }

View File

@ -5,7 +5,7 @@ use iced::{
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub fn main() { pub fn main() -> iced::Result {
Todos::run(Settings::default()) Todos::run(Settings::default())
} }

View File

@ -4,7 +4,7 @@ use iced::{
Sandbox, Scrollable, Settings, Slider, Space, Text, TextInput, Sandbox, Scrollable, Settings, Slider, Space, Text, TextInput,
}; };
pub fn main() { pub fn main() -> iced::Result {
env_logger::init(); env_logger::init();
Tour::run(Settings::default()) Tour::run(Settings::default())

View File

@ -26,7 +26,7 @@ pub(crate) use iced_graphics::Transformation;
#[doc(no_inline)] #[doc(no_inline)]
pub use widget::*; pub use widget::*;
pub use iced_graphics::Viewport; pub use iced_graphics::{Error, Viewport};
pub use iced_native::{ pub use iced_native::{
Background, Color, Command, HorizontalAlignment, Length, Vector, Background, Color, Command, HorizontalAlignment, Length, Vector,
VerticalAlignment, VerticalAlignment,

View File

@ -1,4 +1,4 @@
use crate::{Backend, Color, Renderer, Settings, Viewport}; use crate::{Backend, Color, Error, Renderer, Settings, Viewport};
use core::ffi::c_void; use core::ffi::c_void;
use glow::HasContext; use glow::HasContext;
@ -18,7 +18,7 @@ impl iced_graphics::window::GLCompositor for Compositor {
unsafe fn new( unsafe fn new(
settings: Self::Settings, settings: Self::Settings,
loader_function: impl FnMut(&str) -> *const c_void, loader_function: impl FnMut(&str) -> *const c_void,
) -> (Self, Self::Renderer) { ) -> Result<(Self, Self::Renderer), Error> {
let gl = glow::Context::from_loader_function(loader_function); let gl = glow::Context::from_loader_function(loader_function);
// Enable auto-conversion from/to sRGB // Enable auto-conversion from/to sRGB
@ -33,7 +33,7 @@ impl iced_graphics::window::GLCompositor for Compositor {
let renderer = Renderer::new(Backend::new(&gl, settings)); let renderer = Renderer::new(Backend::new(&gl, settings));
(Self { gl }, renderer) Ok((Self { gl }, renderer))
} }
fn sample_count(settings: &Settings) -> u32 { fn sample_count(settings: &Settings) -> u32 {

View File

@ -1,5 +1,5 @@
//! Create interactive, native cross-platform applications. //! Create interactive, native cross-platform applications.
use crate::{mouse, Executor, Runtime, Size}; use crate::{mouse, Error, Executor, Runtime, Size};
use iced_graphics::window; use iced_graphics::window;
use iced_graphics::Viewport; use iced_graphics::Viewport;
use iced_winit::application; use iced_winit::application;
@ -16,7 +16,8 @@ pub use iced_winit::{program, Program};
pub fn run<A, E, C>( pub fn run<A, E, C>(
settings: Settings<A::Flags>, settings: Settings<A::Flags>,
compositor_settings: C::Settings, compositor_settings: C::Settings,
) where ) -> Result<(), Error>
where
A: Application + 'static, A: Application + 'static,
E: Executor + 'static, E: Executor + 'static,
C: window::GLCompositor<Renderer = A::Renderer> + 'static, C: window::GLCompositor<Renderer = A::Renderer> + 'static,
@ -32,7 +33,7 @@ pub fn run<A, E, C>(
let event_loop = EventLoop::with_user_event(); let event_loop = EventLoop::with_user_event();
let mut runtime = { let mut runtime = {
let executor = E::new().expect("Create executor"); let executor = E::new().map_err(Error::ExecutorCreationFailed)?;
let proxy = Proxy::new(event_loop.create_proxy()); let proxy = Proxy::new(event_loop.create_proxy());
Runtime::new(executor, proxy) Runtime::new(executor, proxy)
@ -61,7 +62,16 @@ pub fn run<A, E, C>(
.with_vsync(true) .with_vsync(true)
.with_multisampling(C::sample_count(&compositor_settings) as u16) .with_multisampling(C::sample_count(&compositor_settings) as u16)
.build_windowed(builder, &event_loop) .build_windowed(builder, &event_loop)
.expect("Open window"); .map_err(|error| {
use glutin::CreationError;
match error {
CreationError::Window(error) => {
Error::WindowCreationFailed(error)
}
_ => Error::GraphicsAdapterNotFound,
}
})?;
#[allow(unsafe_code)] #[allow(unsafe_code)]
unsafe { unsafe {
@ -85,7 +95,7 @@ pub fn run<A, E, C>(
let (mut compositor, mut renderer) = unsafe { let (mut compositor, mut renderer) = unsafe {
C::new(compositor_settings, |address| { C::new(compositor_settings, |address| {
context.get_proc_address(address) context.get_proc_address(address)
}) })?
}; };
let mut state = program::State::new( let mut state = program::State::new(

View File

@ -15,7 +15,7 @@ pub use iced_native::*;
pub mod application; pub mod application;
pub use iced_winit::settings; pub use iced_winit::settings;
pub use iced_winit::Mode; pub use iced_winit::{Error, Mode};
#[doc(no_inline)] #[doc(no_inline)]
pub use application::Application; pub use application::Application;

View File

@ -15,6 +15,7 @@ opengl = []
bytemuck = "1.2" bytemuck = "1.2"
glam = "0.9" glam = "0.9"
raw-window-handle = "0.3" raw-window-handle = "0.3"
thiserror = "1.0"
[dependencies.iced_native] [dependencies.iced_native]
version = "0.2" version = "0.2"

7
graphics/src/error.rs Normal file
View File

@ -0,0 +1,7 @@
/// A graphical error that occurred while running an application.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// A suitable graphics adapter or device could not be found
#[error("a suitable graphics adapter or device could not be found")]
AdapterNotFound,
}

View File

@ -9,6 +9,7 @@
#![forbid(rust_2018_idioms)] #![forbid(rust_2018_idioms)]
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
mod antialiasing; mod antialiasing;
mod error;
mod primitive; mod primitive;
mod renderer; mod renderer;
mod transformation; mod transformation;
@ -29,6 +30,7 @@ pub use widget::*;
pub use antialiasing::Antialiasing; pub use antialiasing::Antialiasing;
pub use backend::Backend; pub use backend::Backend;
pub use defaults::Defaults; pub use defaults::Defaults;
pub use error::Error;
pub use layer::Layer; pub use layer::Layer;
pub use primitive::Primitive; pub use primitive::Primitive;
pub use renderer::Renderer; pub use renderer::Renderer;

View File

@ -1,4 +1,4 @@
use crate::{Color, Viewport}; use crate::{Color, Error, Viewport};
use iced_native::mouse; use iced_native::mouse;
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
@ -19,7 +19,7 @@ pub trait Compositor: Sized {
/// Creates a new [`Backend`]. /// Creates a new [`Backend`].
/// ///
/// [`Backend`]: trait.Backend.html /// [`Backend`]: trait.Backend.html
fn new(settings: Self::Settings) -> (Self, Self::Renderer); fn new(settings: Self::Settings) -> Result<(Self, Self::Renderer), Error>;
/// Crates a new [`Surface`] for the given window. /// Crates a new [`Surface`] for the given window.
/// ///

View File

@ -1,4 +1,4 @@
use crate::{Color, Size, Viewport}; use crate::{Color, Error, Size, Viewport};
use iced_native::mouse; use iced_native::mouse;
use core::ffi::c_void; use core::ffi::c_void;
@ -41,7 +41,7 @@ pub trait GLCompositor: Sized {
unsafe fn new( unsafe fn new(
settings: Self::Settings, settings: Self::Settings,
loader_function: impl FnMut(&str) -> *const c_void, loader_function: impl FnMut(&str) -> *const c_void,
) -> (Self, Self::Renderer); ) -> Result<(Self, Self::Renderer), Error>;
/// Returns the amount of samples that should be used when configuring /// Returns the amount of samples that should be used when configuring
/// an OpenGL context for this [`Compositor`]. /// an OpenGL context for this [`Compositor`].

View File

@ -1,6 +1,5 @@
use crate::{ use crate::window;
window, Color, Command, Element, Executor, Settings, Subscription, use crate::{Color, Command, Element, Executor, Settings, Subscription};
};
/// An interactive cross-platform application. /// An interactive cross-platform application.
/// ///
@ -59,7 +58,7 @@ use crate::{
/// ```no_run /// ```no_run
/// use iced::{executor, Application, Command, Element, Settings, Text}; /// use iced::{executor, Application, Command, Element, Settings, Text};
/// ///
/// pub fn main() { /// pub fn main() -> iced::Result {
/// Hello::run(Settings::default()) /// Hello::run(Settings::default())
/// } /// }
/// ///
@ -204,12 +203,13 @@ pub trait Application: Sized {
/// Runs the [`Application`]. /// Runs the [`Application`].
/// ///
/// On native platforms, this method will take control of the current thread /// On native platforms, this method will take control of the current thread
/// and __will NOT return__. /// and __will NOT return__ unless there is an [`Error`] during startup.
/// ///
/// It should probably be that last thing you call in your `main` function. /// It should probably be that last thing you call in your `main` function.
/// ///
/// [`Application`]: trait.Application.html /// [`Application`]: trait.Application.html
fn run(settings: Settings<Self::Flags>) /// [`Error`]: enum.Error.html
fn run(settings: Settings<Self::Flags>) -> crate::Result
where where
Self: 'static, Self: 'static,
{ {
@ -226,15 +226,19 @@ pub trait Application: Sized {
..crate::renderer::Settings::default() ..crate::renderer::Settings::default()
}; };
crate::runtime::application::run::< Ok(crate::runtime::application::run::<
Instance<Self>, Instance<Self>,
Self::Executor, Self::Executor,
crate::renderer::window::Compositor, crate::renderer::window::Compositor,
>(settings.into(), renderer_settings); >(settings.into(), renderer_settings)?)
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
<Instance<Self> as iced_web::Application>::run(settings.flags); {
<Instance<Self> as iced_web::Application>::run(settings.flags);
Ok(())
}
} }
} }

34
src/error.rs Normal file
View File

@ -0,0 +1,34 @@
use iced_futures::futures;
/// An error that occurred while running an application.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// The futures executor could not be created.
#[error("the futures executor could not be created")]
ExecutorCreationFailed(futures::io::Error),
/// The application window could not be created.
#[error("the application window could not be created")]
WindowCreationFailed(Box<dyn std::error::Error>),
/// A suitable graphics adapter or device could not be found.
#[error("a suitable graphics adapter or device could not be found")]
GraphicsAdapterNotFound,
}
#[cfg(not(target_arch = "wasm32"))]
impl From<iced_winit::Error> for Error {
fn from(error: iced_winit::Error) -> Error {
match error {
iced_winit::Error::ExecutorCreationFailed(error) => {
Error::ExecutorCreationFailed(error)
}
iced_winit::Error::WindowCreationFailed(error) => {
Error::WindowCreationFailed(Box::new(error))
}
iced_winit::Error::GraphicsAdapterNotFound => {
Error::GraphicsAdapterNotFound
}
}
}
}

View File

@ -181,6 +181,8 @@
#![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr(docsrs, feature(doc_cfg))]
mod application; mod application;
mod element; mod element;
mod error;
mod result;
mod sandbox; mod sandbox;
pub mod executor; pub mod executor;
@ -225,7 +227,9 @@ pub use widget::*;
pub use application::Application; pub use application::Application;
pub use element::Element; pub use element::Element;
pub use error::Error;
pub use executor::Executor; pub use executor::Executor;
pub use result::Result;
pub use sandbox::Sandbox; pub use sandbox::Sandbox;
pub use settings::Settings; pub use settings::Settings;

6
src/result.rs Normal file
View File

@ -0,0 +1,6 @@
use crate::Error;
/// The result of running an [`Application`].
///
/// [`Application`]: trait.Application.html
pub type Result = std::result::Result<(), Error>;

View File

@ -1,5 +1,6 @@
use crate::executor;
use crate::{ use crate::{
executor, Application, Color, Command, Element, Settings, Subscription, Application, Color, Command, Element, Error, Settings, Subscription,
}; };
/// A sandboxed [`Application`]. /// A sandboxed [`Application`].
@ -64,7 +65,7 @@ use crate::{
/// ```no_run /// ```no_run
/// use iced::{Element, Sandbox, Settings, Text}; /// use iced::{Element, Sandbox, Settings, Text};
/// ///
/// pub fn main() { /// pub fn main() -> iced::Result {
/// Hello::run(Settings::default()) /// Hello::run(Settings::default())
/// } /// }
/// ///
@ -159,7 +160,7 @@ pub trait Sandbox {
/// It should probably be that last thing you call in your `main` function. /// It should probably be that last thing you call in your `main` function.
/// ///
/// [`Sandbox`]: trait.Sandbox.html /// [`Sandbox`]: trait.Sandbox.html
fn run(settings: Settings<()>) fn run(settings: Settings<()>) -> Result<(), Error>
where where
Self: 'static + Sized, Self: 'static + Sized,
{ {

View File

@ -36,7 +36,9 @@ mod backend;
mod quad; mod quad;
mod text; mod text;
pub use iced_graphics::{Antialiasing, Color, Defaults, Primitive, Viewport}; pub use iced_graphics::{
Antialiasing, Color, Defaults, Error, Primitive, Viewport,
};
pub use wgpu; pub use wgpu;
pub use backend::Backend; pub use backend::Backend;

View File

@ -1,7 +1,6 @@
use crate::{Backend, Color, Renderer, Settings}; use crate::{Backend, Color, Error, Renderer, Settings, Viewport};
use futures::task::SpawnExt; use futures::task::SpawnExt;
use iced_graphics::Viewport;
use iced_native::{futures, mouse}; use iced_native::{futures, mouse};
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
@ -82,13 +81,13 @@ impl iced_graphics::window::Compositor for Compositor {
type Surface = wgpu::Surface; type Surface = wgpu::Surface;
type SwapChain = wgpu::SwapChain; type SwapChain = wgpu::SwapChain;
fn new(settings: Self::Settings) -> (Self, Renderer) { fn new(settings: Self::Settings) -> Result<(Self, Renderer), Error> {
let compositor = futures::executor::block_on(Self::request(settings)) let compositor = futures::executor::block_on(Self::request(settings))
.expect("Could not find a suitable graphics adapter"); .ok_or(Error::AdapterNotFound)?;
let backend = compositor.create_backend(); let backend = compositor.create_backend();
(compositor, Renderer::new(backend)) Ok((compositor, Renderer::new(backend)))
} }
fn create_surface<W: HasRawWindowHandle>( fn create_surface<W: HasRawWindowHandle>(

View File

@ -17,6 +17,7 @@ debug = ["iced_native/debug"]
winit = "0.22" winit = "0.22"
window_clipboard = "0.1" window_clipboard = "0.1"
log = "0.4" log = "0.4"
thiserror = "1.0"
[dependencies.iced_native] [dependencies.iced_native]
version = "0.2" version = "0.2"
@ -26,5 +27,9 @@ path = "../native"
version = "0.1" version = "0.1"
path = "../graphics" path = "../graphics"
[dependencies.iced_futures]
version = "0.1"
path = "../futures"
[target.'cfg(target_os = "windows")'.dependencies.winapi] [target.'cfg(target_os = "windows")'.dependencies.winapi]
version = "0.3.6" version = "0.3.6"

View File

@ -1,7 +1,9 @@
//! Create interactive, native cross-platform applications. //! Create interactive, native cross-platform applications.
use crate::conversion;
use crate::mouse;
use crate::{ use crate::{
conversion, mouse, Clipboard, Color, Command, Debug, Executor, Mode, Proxy, Clipboard, Color, Command, Debug, Error, Executor, Mode, Proxy, Runtime,
Runtime, Settings, Size, Subscription, Settings, Size, Subscription,
}; };
use iced_graphics::window; use iced_graphics::window;
use iced_graphics::Viewport; use iced_graphics::Viewport;
@ -108,7 +110,8 @@ pub trait Application: Program {
pub fn run<A, E, C>( pub fn run<A, E, C>(
settings: Settings<A::Flags>, settings: Settings<A::Flags>,
compositor_settings: C::Settings, compositor_settings: C::Settings,
) where ) -> Result<(), Error>
where
A: Application + 'static, A: Application + 'static,
E: Executor + 'static, E: Executor + 'static,
C: window::Compositor<Renderer = A::Renderer> + 'static, C: window::Compositor<Renderer = A::Renderer> + 'static,
@ -123,7 +126,7 @@ pub fn run<A, E, C>(
let event_loop = EventLoop::with_user_event(); let event_loop = EventLoop::with_user_event();
let mut runtime = { let mut runtime = {
let executor = E::new().expect("Create executor"); let executor = E::new().map_err(Error::ExecutorCreationFailed)?;
let proxy = Proxy::new(event_loop.create_proxy()); let proxy = Proxy::new(event_loop.create_proxy());
Runtime::new(executor, proxy) Runtime::new(executor, proxy)
@ -145,7 +148,7 @@ pub fn run<A, E, C>(
.window .window
.into_builder(&title, mode, event_loop.primary_monitor()) .into_builder(&title, mode, event_loop.primary_monitor())
.build(&event_loop) .build(&event_loop)
.expect("Open window"); .map_err(Error::WindowCreationFailed)?;
let clipboard = Clipboard::new(&window); let clipboard = Clipboard::new(&window);
// TODO: Encode cursor availability in the type-system // TODO: Encode cursor availability in the type-system
@ -160,7 +163,7 @@ pub fn run<A, E, C>(
); );
let mut resized = false; let mut resized = false;
let (mut compositor, mut renderer) = C::new(compositor_settings); let (mut compositor, mut renderer) = C::new(compositor_settings)?;
let surface = compositor.create_surface(&window); let surface = compositor.create_surface(&window);

27
winit/src/error.rs Normal file
View File

@ -0,0 +1,27 @@
use iced_futures::futures;
/// An error that occurred while running an application.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// The futures executor could not be created.
#[error("the futures executor could not be created")]
ExecutorCreationFailed(futures::io::Error),
/// The application window could not be created.
#[error("the application window could not be created")]
WindowCreationFailed(winit::error::OsError),
/// A suitable graphics adapter or device could not be found.
#[error("a suitable graphics adapter or device could not be found")]
GraphicsAdapterNotFound,
}
impl From<iced_graphics::Error> for Error {
fn from(error: iced_graphics::Error) -> Error {
match error {
iced_graphics::Error::AdapterNotFound => {
Error::GraphicsAdapterNotFound
}
}
}
}

View File

@ -30,11 +30,13 @@ pub mod conversion;
pub mod settings; pub mod settings;
mod clipboard; mod clipboard;
mod error;
mod mode; mod mode;
mod proxy; mod proxy;
pub use application::Application; pub use application::Application;
pub use clipboard::Clipboard; pub use clipboard::Clipboard;
pub use error::Error;
pub use mode::Mode; pub use mode::Mode;
pub use proxy::Proxy; pub use proxy::Proxy;
pub use settings::Settings; pub use settings::Settings;