use crate::domain::spm_builder::*;
use crate::utils::theme_colors::*;
use iced::widget::{center_x, checkbox, column, text};
use iced::{Color, Element};
pub type AppElement<'a> = Element<'a, Message>;
#[derive(Debug, Clone)]
pub enum Message {
ChangelogToggled(bool),
ReadmeToggled(bool),
SwiftPackageIndexToggled(bool),
SwiftLintToggled(bool),
IosToggled(bool),
MacOsToggled(bool),
TvOsToggled(bool),
WatchOsToggled(bool),
VisionOsToggled(bool),
XCTestToggled(bool),
SwiftTestingToggled(bool),
InputChanged(String),
GenerateSPM,
}
#[derive(Default)]
pub struct SpmView {
changelog: bool,
readme: bool,
swift_package_index: bool,
swiftlint: bool,
ios: bool,
macos: bool,
tvos: bool,
watchos: bool,
visionos: bool,
xctest: bool,
swift_testing: bool,
input_content: String,
platform_error: bool,
test_framework_error: bool,
}
pub fn run() -> iced::Result {
iced::application(SpmView::default, SpmView::update, SpmView::view).run()
}
impl SpmView {
pub fn update(&mut self, message: Message) {
match message {
Message::ChangelogToggled(val) => self.changelog = val,
Message::ReadmeToggled(val) => self.readme = val,
Message::SwiftPackageIndexToggled(val) => self.swift_package_index = val,
Message::SwiftLintToggled(val) => self.swiftlint = val,
Message::IosToggled(val) => {
if val {
self.ios = true;
self.macos = false;
self.tvos = false;
self.watchos = false;
self.visionos = false;
self.platform_error = false;
} else {
self.ios = false;
}
}
Message::MacOsToggled(val) => {
if val {
self.ios = false;
self.macos = true;
self.tvos = false;
self.watchos = false;
self.visionos = false;
self.platform_error = false;
} else {
self.macos = false;
}
}
Message::TvOsToggled(val) => {
if val {
self.ios = false;
self.macos = false;
self.tvos = true;
self.watchos = false;
self.visionos = false;
self.platform_error = false;
} else {
self.tvos = false;
}
}
Message::WatchOsToggled(val) => {
if val {
self.ios = false;
self.macos = false;
self.tvos = false;
self.watchos = true;
self.visionos = false;
self.platform_error = false;
} else {
self.watchos = false;
}
}
Message::VisionOsToggled(val) => {
if val {
self.ios = false;
self.macos = false;
self.tvos = false;
self.watchos = false;
self.visionos = true;
self.platform_error = false;
} else {
self.visionos = false;
}
}
Message::XCTestToggled(val) => {
if val {
self.xctest = true;
self.swift_testing = false;
self.test_framework_error = false;
} else {
self.xctest = false;
}
}
Message::SwiftTestingToggled(val) => {
if val {
self.xctest = false;
self.swift_testing = true;
self.test_framework_error = false;
} else {
self.swift_testing = false;
}
}
Message::InputChanged(s) => self.input_content = s,
Message::GenerateSPM => {
let mut platforms = Vec::new();
if self.ios {
platforms.push("iOS");
}
if self.macos {
platforms.push("macOS");
}
if self.tvos {
platforms.push("tvOS");
}
if self.watchos {
platforms.push("watchOS");
}
if self.visionos {
platforms.push("visionOS");
}
if platforms.is_empty() {
self.platform_error = true;
return;
} else {
self.platform_error = false;
}
let test_framework = if self.xctest {
"XCTest"
} else if self.swift_testing {
"Swift Testing"
} else {
self.test_framework_error = true;
return;
};
self.test_framework_error = false;
let mut project_name = self.input_content.clone();
if project_name.trim().is_empty() {
project_name = "Library".to_string();
}
let mut files = Vec::new();
if self.changelog {
files.push("Changelog");
}
if self.readme {
files.push("Readme");
}
if self.swift_package_index {
files.push("Swift Package Index");
}
if self.swiftlint {
files.push("SwiftLint");
}
tokio::spawn(async move {
if (SpmBuilder::create(&project_name, &files, platforms.as_slice(), test_framework))
.is_ok()
{
let command = format!("cd {} && open Package.swift", project_name);
let _ = std::process::Command::new("sh")
.arg("-c")
.arg(&command)
.spawn();
}
});
}
}
}
pub fn view(&self) -> AppElement<'_> {
column![
self.header_view(),
self.input_view(),
self.files_title_view(),
self.files_checkboxes_view(),
self.platforms_title_view(),
self.platforms_checkboxes_view(),
self.error_platform_view(),
self.test_framework_title_view(),
self.test_framework_checkboxes_view(),
self.error_test_framework_view(),
self.generate_button_view(),
]
.spacing(16)
.into()
}
fn header_view(&self) -> AppElement<'_> {
column![
center_x(
text("SPM Swift Package")
.color(ThemeColors::ORANGE)
.size(32)
)
.height(20),
center_x(
text(
"Command Line Tools for macOS to create Swift Package Manager projects with desirable files."
)
.color(ThemeColors::GRAY)
.size(14)
)
.padding(16),
]
.spacing(16)
.into()
}
fn input_view(&self) -> AppElement<'_> {
iced::widget::Container::new(
iced::widget::text_input("Insert the name of the project", &self.input_content)
.on_input(Message::InputChanged)
.padding(8)
.size(18),
)
.padding([0, 24])
.into()
}
fn files_title_view(&self) -> AppElement<'_> {
let title = text("Choose the files you want to include in your project:")
.color(Color::WHITE)
.size(18);
iced::widget::Container::new(title).padding([0, 24]).into()
}
fn platforms_title_view(&self) -> AppElement<'_> {
let title = text("Choose the platforms you want to include in your project:")
.color(Color::WHITE)
.size(18);
iced::widget::Container::new(title).padding([0, 24]).into()
}
fn test_framework_title_view(&self) -> AppElement<'_> {
let title = text("Choose the test framework:")
.color(Color::WHITE)
.size(18);
iced::widget::Container::new(title).padding([0, 24]).into()
}
fn files_checkboxes_view(&self) -> AppElement<'_> {
let mut col = column![];
for checkbox in self.view_files_checkboxes() {
col = col.push(checkbox);
}
col.spacing(8).into()
}
fn platforms_checkboxes_view(&self) -> AppElement<'_> {
let mut col = column![];
for checkbox in self.view_platforms_checkboxes() {
col = col.push(checkbox);
}
col.spacing(8).into()
}
fn test_framework_checkboxes_view(&self) -> AppElement<'_> {
let mut col = column![];
for checkbox in self.view_test_framework_checkboxes() {
col = col.push(checkbox);
}
col.spacing(8).into()
}
fn generate_button_view(&self) -> AppElement<'_> {
iced::widget::Container::new(
iced::widget::button(text("Generate SPM").size(16).color(Color::WHITE))
.on_press(Message::GenerateSPM),
)
.padding([8, 24])
.into()
}
fn error_platform_view(&self) -> AppElement<'_> {
if self.platform_error {
iced::widget::Container::new(
text("Please select at least one platform.")
.color([1.0, 0.2, 0.2])
.size(16),
)
.padding([0, 24])
.into()
} else {
iced::widget::Container::new("").into()
}
}
fn error_test_framework_view(&self) -> AppElement<'_> {
if self.test_framework_error {
iced::widget::Container::new(
text("Please select a test framework.")
.color([1.0, 0.2, 0.2])
.size(16),
)
.padding([0, 24])
.into()
} else {
iced::widget::Container::new("").into()
}
}
fn view_files_checkboxes(&self) -> Vec<AppElement<'_>> {
vec![
self.checkbox_row("Changelog", self.changelog, Message::ChangelogToggled),
self.checkbox_row("Readme", self.readme, Message::ReadmeToggled),
self.checkbox_row(
"Swift Package Index",
self.swift_package_index,
Message::SwiftPackageIndexToggled,
),
self.checkbox_row("SwiftLint", self.swiftlint, Message::SwiftLintToggled),
]
}
fn view_platforms_checkboxes(&self) -> Vec<AppElement<'_>> {
vec![
self.checkbox_row("iOS", self.ios, Message::IosToggled),
self.checkbox_row("macOS", self.macos, Message::MacOsToggled),
self.checkbox_row("tvOS", self.tvos, Message::TvOsToggled),
self.checkbox_row("watchOS", self.watchos, Message::WatchOsToggled),
self.checkbox_row("visionOS", self.visionos, Message::VisionOsToggled),
]
}
fn view_test_framework_checkboxes(&self) -> Vec<AppElement<'_>> {
vec![
self.checkbox_row("XCTest", self.xctest, Message::XCTestToggled),
self.checkbox_row(
"Swift Testing",
self.swift_testing,
Message::SwiftTestingToggled,
),
]
}
fn checkbox_row<'a>(
&self,
label: &'a str,
value: bool,
on_toggle: fn(bool) -> Message,
) -> AppElement<'a> {
iced::widget::Container::new(checkbox(value).label(label).on_toggle(on_toggle))
.padding([0, 24])
.into()
}
}