diff --git a/config.toml b/config.toml
index 5f49e8d..d633812 100644
--- a/config.toml
+++ b/config.toml
@@ -1,31 +1,2 @@
-[general]
name = "yuzu"
-installing_message = "Reminder: yuzu is an experimental emulator. Stuff will break!"
-
-[[packages]]
-name = "yuzu Nightly"
-description = "The nightly build of yuzu contains already reviewed and tested features."
- [packages.source]
- name = "github"
- match = "^yuzu-#PLATFORM#(-mingw)?-[0-9]*-[0-9a-f]*.zip$"
- [packages.source.config]
- repo = "yuzu-emu/yuzu-nightly"
-
-[[packages]]
-name = "yuzu Canary"
-description = "The canary build of yuzu has additional features that are still waiting on review."
- [packages.source]
- name = "github"
- match = "^yuzu-#PLATFORM#(-mingw)?-[0-9]*-[0-9a-f]*.zip$"
- [packages.source.config]
- repo = "yuzu-emu/yuzu-canary"
-
-[[packages]]
-name = "Test package"
-description = "Just a testing package"
-default = true
- [packages.source]
- name = "github"
- match = "^TestPackage.zip$"
- [packages.source.config]
- repo = "j-selby/test-installer"
+target_url = "https://raw.githubusercontent.com/j-selby/test-installer/master/config.v1.toml"
diff --git a/src/config.rs b/src/config.rs
index 8f1a17c..b5eda7d 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -30,14 +30,26 @@ pub struct PackageDescription {
/// Describes the application itself.
#[derive(Debug, Deserialize, Serialize, Clone)]
-pub struct GeneralConfig {
+pub struct BaseAttributes {
pub name: String,
- pub installing_message: String,
+ pub target_url: String,
+}
+
+impl BaseAttributes {
+ /// Serialises as a JSON string.
+ pub fn to_json_str(&self) -> Result {
+ serde_json::to_string(self)
+ }
+
+ /// Builds a configuration from a specified TOML string.
+ pub fn from_toml_str(contents: &str) -> Result {
+ toml::from_str(contents)
+ }
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Config {
- pub general: GeneralConfig,
+ pub installing_message: String,
pub packages: Vec,
}
diff --git a/src/http.rs b/src/http.rs
index 7ffc4a2..7fc831f 100644
--- a/src/http.rs
+++ b/src/http.rs
@@ -8,6 +8,19 @@ use reqwest;
use std::io::Read;
+/// Downloads a text file from the specified URL.
+pub fn download_text(url: &str) -> Result {
+ // TODO: Decrease check time
+ let mut client = match reqwest::get(url) {
+ Ok(v) => v,
+ Err(v) => return Err(format!("Failed to GET resource: {:?}", v)),
+ };
+
+ client
+ .text()
+ .map_err(|v| format!("Failed to get text from resource: {:?}", v))
+}
+
/// Streams a file from a HTTP server.
pub fn stream_file(url: &str, mut callback: F) -> Result<(), String>
where
diff --git a/src/installer.rs b/src/installer.rs
index 219f5f0..4f35a47 100644
--- a/src/installer.rs
+++ b/src/installer.rs
@@ -13,6 +13,7 @@ use std::path::PathBuf;
use std::sync::mpsc::Sender;
+use config::BaseAttributes;
use config::Config;
use sources::types::Version;
@@ -36,7 +37,8 @@ pub enum InstallMessage {
/// The installer framework contains metadata about packages, what is installable, what isn't,
/// etc.
pub struct InstallerFramework {
- pub config: Config,
+ pub base_attributes: BaseAttributes,
+ pub config: Option,
pub database: Vec,
pub install_path: Option,
pub preexisting_install: bool,
@@ -64,13 +66,13 @@ pub struct LocalInstallation {
impl InstallerFramework {
/// Returns a copy of the configuration.
- pub fn get_config(&self) -> Config {
+ pub fn get_config(&self) -> Option {
self.config.clone()
}
/// Returns the default install path.
pub fn get_default_path(&self) -> Option {
- let app_name = &self.config.general.name;
+ let app_name = &self.base_attributes.name;
let base_dir = match var("LOCALAPPDATA") {
Ok(path) => PathBuf::from(path),
@@ -194,9 +196,10 @@ impl InstallerFramework {
}
/// Creates a new instance of the Installer Framework with a specified Config.
- pub fn new(config: Config) -> Self {
+ pub fn new(attrs: BaseAttributes) -> Self {
InstallerFramework {
- config,
+ base_attributes: attrs,
+ config: None,
database: Vec::new(),
install_path: None,
preexisting_install: false,
@@ -207,7 +210,7 @@ impl InstallerFramework {
/// Creates a new instance of the Installer Framework with a specified Config, managing
/// a pre-existing installation.
- pub fn new_with_db(config: Config, install_path: &Path) -> Result {
+ pub fn new_with_db(attrs: BaseAttributes, install_path: &Path) -> Result {
let path = install_path.to_owned();
let metadata_path = path.join("metadata.json");
let metadata_file = match File::open(metadata_path) {
@@ -221,7 +224,8 @@ impl InstallerFramework {
};
Ok(InstallerFramework {
- config,
+ base_attributes: attrs,
+ config: None,
database,
install_path: Some(path),
preexisting_install: true,
diff --git a/src/logging.rs b/src/logging.rs
index 88e2720..b80ded6 100644
--- a/src/logging.rs
+++ b/src/logging.rs
@@ -17,7 +17,8 @@ pub fn setup_logger() -> Result<(), fern::InitError> {
record.level(),
message
))
- }).level(log::LevelFilter::Info)
+ })
+ .level(log::LevelFilter::Info)
.chain(io::stdout())
.chain(fern::log_file("installer.log")?)
.apply()?;
@@ -31,6 +32,7 @@ where
Self: Sized,
{
/// Unwraps this object. See `unwrap()`.
+ #[inline]
fn log_unwrap(self) -> T {
self.log_expect("Failed to unwrap")
}
@@ -40,6 +42,7 @@ where
}
impl LoggingErrors for Result {
+ #[inline]
fn log_expect(self, msg: &str) -> T {
match self {
Ok(v) => v,
@@ -52,6 +55,7 @@ impl LoggingErrors for Result {
}
impl LoggingErrors for Option {
+ #[inline]
fn log_expect(self, msg: &str) -> T {
match self {
Some(v) => v,
diff --git a/src/main.rs b/src/main.rs
index 6cb4954..16797ca 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -50,8 +50,6 @@ mod tasks;
use web_view::*;
-use config::Config;
-
use installer::InstallerFramework;
#[cfg(windows)]
@@ -71,6 +69,8 @@ use clap::App;
use clap::Arg;
use log::Level;
+use config::BaseAttributes;
+
// TODO: Fetch this over a HTTP request?
static RAW_CONFIG: &'static str = include_str!("../config.toml");
@@ -83,9 +83,10 @@ enum CallbackType {
fn main() {
logging::setup_logger().expect("Unable to setup logging!");
- let config = Config::from_toml_str(RAW_CONFIG).log_expect("Config file could not be read");
+ let config =
+ BaseAttributes::from_toml_str(RAW_CONFIG).log_expect("Config file could not be read");
- let app_name = config.general.name.clone();
+ let app_name = config.name.clone();
let matches = App::new(format!("{} installer", app_name))
.version(env!("CARGO_PKG_VERSION"))
@@ -96,7 +97,8 @@ fn main() {
.value_name("TARGET")
.help("Launches the specified executable after checking for updates")
.takes_value(true),
- ).get_matches();
+ )
+ .get_matches();
info!("{} installer", app_name);
diff --git a/src/rest.rs b/src/rest.rs
index 7f6fdcd..d874ec9 100644
--- a/src/rest.rs
+++ b/src/rest.rs
@@ -32,6 +32,10 @@ use installer::InstallerFramework;
use logging::LoggingErrors;
use std::process::Command;
+use http;
+
+use config::Config;
+
#[derive(Serialize)]
struct FileSelection {
path: Option,
@@ -55,7 +59,8 @@ impl WebServer {
Ok(WebService {
framework: framework.clone(),
})
- }).log_expect("Failed to bind to port");
+ })
+ .log_expect("Failed to bind to port");
server.run().log_expect("Failed to run HTTP server");
});
@@ -79,16 +84,16 @@ impl Service for WebService {
fn call(&self, req: Self::Request) -> Self::Future {
Box::new(future::ok(match (req.method(), req.path()) {
// This endpoint should be usable directly from a
+