Split modules

This commit is contained in:
Jarrod Doyle 2024-02-05 15:11:23 +00:00
parent 7c49e977b0
commit f874cef96d
Signed by: Jayrude
GPG Key ID: 38B57B16E7C0ADF7
3 changed files with 110 additions and 95 deletions

80
src/application.rs Normal file
View File

@ -0,0 +1,80 @@
use std::{path::PathBuf, sync::Arc};
use iced::{
executor,
widget::{button, column, row, text, text_editor},
Application, Command, Element, Theme,
};
use crate::{
file::{default_file, load_file, pick_file},
Error,
};
#[derive(Debug, Clone)]
pub enum Message {
Open,
Edit(text_editor::Action),
FileOpened(Result<(PathBuf, Arc<String>), Error>),
}
pub struct BookManagerApp {
book_path: Option<PathBuf>,
book_content: text_editor::Content,
io_error: Option<Error>,
}
impl Application for BookManagerApp {
type Executor = executor::Default;
type Flags = ();
type Message = Message;
type Theme = Theme;
fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
(
Self {
book_path: None,
book_content: text_editor::Content::new(),
io_error: None,
},
Command::perform(load_file(default_file()), Message::FileOpened),
)
}
fn title(&self) -> String {
String::from("Thief Book Manager")
}
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
match message {
Message::Edit(action) => self.book_content.perform(action),
Message::FileOpened(result) => match result {
Ok((path, content)) => {
self.book_content = text_editor::Content::with_text(&content);
self.book_path = Some(path);
}
Err(error) => self.io_error = Some(error),
},
Message::Open => {
return Command::perform(pick_file(), Message::FileOpened);
}
}
Command::none()
}
fn view(&self) -> Element<'_, Self::Message> {
let hello_world = text("Hello, world!");
let controls = row![button("Open").on_press(Message::Open)];
let active_editor = text_editor(&self.book_content).on_action(Message::Edit);
column![hello_world, controls, active_editor]
.spacing(10)
.padding(10)
.into()
}
fn theme(&self) -> Theme {
Theme::Dark
}
}

25
src/file.rs Normal file
View File

@ -0,0 +1,25 @@
use std::{path::PathBuf, sync::Arc};
use crate::Error;
pub async fn load_file(path: PathBuf) -> Result<(PathBuf, Arc<String>), Error> {
let content = tokio::fs::read_to_string(&path)
.await
.map(Arc::new)
.map_err(|error| error.kind())
.map_err(Error::IO)?;
Ok((path, content))
}
pub async fn pick_file() -> Result<(PathBuf, Arc<String>), Error> {
let file_handle = rfd::AsyncFileDialog::new()
.set_title("Choose a file...")
.pick_file()
.await
.ok_or(Error::DialogClosed)?;
load_file(file_handle.path().to_owned()).await
}
pub fn default_file() -> PathBuf {
PathBuf::from(format!("{}/src/main.rs", env!("CARGO_MANIFEST_DIR")))
}

View File

@ -1,78 +1,10 @@
use std::{io, path::PathBuf, sync::Arc}; mod application;
mod file;
use iced::{ use std::io;
executor,
widget::{button, column, row, text, text_editor},
Application, Command, Element, Settings, Theme,
};
#[derive(Debug, Clone)] use application::BookManagerApp;
enum Message { use iced::{Application, Settings};
Open,
Edit(text_editor::Action),
FileOpened(Result<(PathBuf, Arc<String>), Error>),
}
struct BookManagerApp {
book_path: Option<PathBuf>,
book_content: text_editor::Content,
io_error: Option<Error>,
}
impl Application for BookManagerApp {
type Executor = executor::Default;
type Flags = ();
type Message = Message;
type Theme = Theme;
fn new(_flags: Self::Flags) -> (Self, Command<Self::Message>) {
(
Self {
book_path: None,
book_content: text_editor::Content::new(),
io_error: None,
},
Command::perform(load_file(default_file()), Message::FileOpened),
)
}
fn title(&self) -> String {
String::from("Thief Book Manager")
}
fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
match message {
Message::Edit(action) => self.book_content.perform(action),
Message::FileOpened(result) => match result {
Ok((path, content)) => {
self.book_content = text_editor::Content::with_text(&content);
self.book_path = Some(path);
}
Err(error) => self.io_error = Some(error),
},
Message::Open => {
return Command::perform(pick_file(), Message::FileOpened);
}
}
Command::none()
}
fn view(&self) -> Element<'_, Self::Message> {
let hello_world = text("Hello, world!");
let controls = row![button("Open").on_press(Message::Open)];
let active_editor = text_editor(&self.book_content).on_action(Message::Edit);
column![hello_world, controls, active_editor]
.spacing(10)
.padding(10)
.into()
}
fn theme(&self) -> Theme {
Theme::Dark
}
}
fn main() -> iced::Result { fn main() -> iced::Result {
BookManagerApp::run(Settings::default()) BookManagerApp::run(Settings::default())
@ -83,25 +15,3 @@ enum Error {
DialogClosed, DialogClosed,
IO(io::ErrorKind), IO(io::ErrorKind),
} }
async fn load_file(path: PathBuf) -> Result<(PathBuf, Arc<String>), Error> {
let content = tokio::fs::read_to_string(&path)
.await
.map(Arc::new)
.map_err(|error| error.kind())
.map_err(Error::IO)?;
Ok((path, content))
}
async fn pick_file() -> Result<(PathBuf, Arc<String>), Error> {
let file_handle = rfd::AsyncFileDialog::new()
.set_title("Choose a file...")
.pick_file()
.await
.ok_or(Error::DialogClosed)?;
load_file(file_handle.path().to_owned()).await
}
fn default_file() -> PathBuf {
PathBuf::from(format!("{}/src/main.rs", env!("CARGO_MANIFEST_DIR")))
}