enso/app/gui/src/config.rs
Ilya Bogdanov d44ca85197
Refactor integration level so "no project opened" state is possible (#3160)
* refactor: remove invalid comment in ide/lib.rs

* refactor: current_project() returns Option

* refactor: create IDE controller without project

* refactor: handle missing project param in Cloud environment

* refactor: store project name in searcher

So no need in current_project call

* chore: apply rustfmt

* chore: fix tests

* refactor: rename maybe_project_name to project_name

* refactor: move project_name to BackendService::LanguageServer

* refactor: do not use early return in integration.rs

* refactor: use CloneCell instead of RefCell for current_project

* refactor: store model::Project in Searcher controller

* refactor: use expect instead of unwrap in searcher tests

* feat: add new_with_project_model constructor for desktop controller

It might be useful in tests

* chore: fix searcher tests
2021-11-30 11:48:12 +03:00

113 lines
3.8 KiB
Rust

//! This module provides IDE configuration structures.
use crate::prelude::*;
use crate::constants;
use engine_protocol::project_manager::ProjectName;
use enso_config::Args;
use enso_config::ARGS;
// ==============
// === Errors ===
// ==============
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Fail)]
#[fail(display = "Missing program option: {}.", 0)]
pub struct MissingOption(&'static str);
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Fail)]
#[fail(display = "Provided options for both project manager and language server connection.")]
pub struct MutuallyExclusiveOptions;
// ======================
// === BackendService ===
// ======================
/// A Configuration defining to what backend service should IDE connect.
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub enum BackendService {
/// Connect to the project manager. Using the project manager IDE will open or create a
/// specific project and connect to its Language Server.
ProjectManager { endpoint: String },
/// Connect to the language server of some project. The project managing operations will be
/// unavailable.
LanguageServer {
json_endpoint: String,
binary_endpoint: String,
namespace: String,
project_name: String,
},
}
impl Default for BackendService {
fn default() -> Self {
Self::ProjectManager { endpoint: constants::PROJECT_MANAGER_ENDPOINT.into() }
}
}
impl BackendService {
/// Read backend configuration from the web arguments. See also [`web::Arguments`]
/// documentation.
pub fn from_web_arguments(args: &Args) -> FallibleResult<Self> {
if let Some(endpoint) = &args.project_manager {
if args.language_server_rpc.is_some() || args.language_server_data.is_some() {
Err(MutuallyExclusiveOptions.into())
} else {
let endpoint = endpoint.clone();
Ok(Self::ProjectManager { endpoint })
}
} else {
match (&args.language_server_rpc, &args.language_server_data) {
(Some(json_endpoint), Some(binary_endpoint)) => {
let json_endpoint = json_endpoint.clone();
let binary_endpoint = binary_endpoint.clone();
let default_namespace = || constants::DEFAULT_PROJECT_NAMESPACE.to_owned();
let namespace = args.namespace.clone().unwrap_or_else(default_namespace);
let missing_project_name = || MissingOption(args.names().project());
let project_name = args.project.clone().ok_or_else(missing_project_name)?;
Ok(Self::LanguageServer {
json_endpoint,
binary_endpoint,
namespace,
project_name,
})
}
(None, None) => Ok(default()),
(None, _) => Err(MissingOption(args.names().language_server_rpc()).into()),
(_, None) => Err(MissingOption(args.names().language_server_data()).into()),
}
}
}
}
// ===============
// === Startup ===
// ===============
/// Configuration data necessary to initialize IDE.
#[derive(Clone, Debug, Default)]
pub struct Startup {
/// The configuration of connection to the backend service.
pub backend: BackendService,
/// The project name we want to open on startup.
pub project_name: Option<ProjectName>,
}
impl Startup {
/// Read configuration from the web arguments. See also [`web::Arguments`] documentation.
pub fn from_web_arguments() -> FallibleResult<Startup> {
let backend = BackendService::from_web_arguments(&ARGS)?;
let project_name = ARGS.project.clone().map(Into::into);
Ok(Startup { backend, project_name })
}
}